【问题标题】:Why is ElasticSearch match query returning all results?为什么 ElasticSearch 匹配查询返回所有结果?
【发布时间】:2015-03-09 19:38:22
【问题描述】:

我有以下 ElasticSearch 查询,我认为它会返回 email 字段上的所有匹配项,它等于 myemails@email.com

"query": {
  "bool": {
    "must": [
      {
        "match": {
          "email": "myemail@gmail.com"
      }
    }
  ]
}

}

正在搜索的 user 类型的映射如下:

    {
      "users": {
      "mappings": {
         "user": {
            "properties": {
               "email": {
                  "type": "string"
               },
               "name": {
                  "type": "string",
                  "fields": {
                     "raw": {
                        "type": "string",
                        "index": "not_analyzed"
                     }
                  }
               },
               "nickname": {
                  "type": "string"
               },
            }
         }
       }
   }  
     }

以下是 ElasticSearch 返回的结果示例

 [{
    "_index": "users",
    "_type": "user",
    "_id": "54b19c417dcc4fe40d728e2c",
    "_score": 0.23983537,
    "_source": {
    "email": "johnsmith@gmail.com",
    "name": "John Smith",
    "nickname": "jsmith",
 },
 {
    "_index": "users",
    "_type": "user",
    "_id": "9c417dcc4fe40d728e2c54b1",
    "_score": 0.23983537,
    "_source": {
       "email": "myemail@gmail.com",
       "name": "Walter White",
       "nickname": "wwhite",
 },
 {
    "_index": "users",
    "_type": "user",
    "_id": "4fe40d728e2c54b19c417dcc",
    "_score": 0.23983537,
    "_source": {
       "email": "JimmyFallon@gmail.com",
       "name": "Jimmy Fallon",
       "nickname": "jfallon",
}]

根据上述查询,我​​认为这需要与“myemail@gmail.com”作为电子邮件属性值完全匹配。

ElasticSearch DSL 查询需要如何更改才能仅返回电子邮件上的完全匹配。

【问题讨论】:

    标签: node.js elasticsearch elasticsearch-plugin


    【解决方案1】:

    email 字段被标记化,这就是这个异常的原因。 所以当你被索引时发生了什么

    "myemail@gmail.com" => [ "myemail" , "gmail.com" ]

    这样,如果您搜索 myemail 或 gmail.com,您将获得正确匹配。 所以发生的情况是,当您搜索 john@gmail.com 时,分析器也会应用于搜索查询。 因此它被分解成

    "john@gmail.com" => [ "john" , "gmail.com" ]

    这里“gmail.com”标记在搜索词和索引词中很常见,你会得到一个匹配项。

    要克服这种行为,请声明电子邮件;字段为 not_analyzed。那里不会发生标记化,整个字符串将被索引。

    带有“not_analyzed”

    "john@gmail.com" => [ "john@gmail.com" ]

    所以修改映射到这个,你应该很好 -

    {
      "users": {
        "mappings": {
          "user": {
            "properties": {
              "email": {
                "type": "string",
                "index": "not_analyzed"
              },
              "name": {
                "type": "string",
                "fields": {
                  "raw": {
                    "type": "string",
                    "index": "not_analyzed"
                  }
                }
              },
              "nickname": {
                "type": "string"
              }
            }
          }
        }
      }
    }
    

    我已经更准确地描述了这个问题以及解决它的另一种方法here

    【讨论】:

    • 答案中的 URL 已失效。
    • 是的,该 URL 不再可用。我猜这是更新后的网址:qbox.io/blog/elasticsearch-aggregation-custom-analyzer
    • 如果您想要原始标记化怎么办?我和OP有同样的问题。无论查询是什么,都会返回一个特定字段的所有结果。
    • 好的,这是一种在字段上维护标记化的方法,并且仍然对其进行布尔查询:使用 Elasticsearch 5.0 中提供的.keyword 功能。检查答案herehere
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    相关资源
    最近更新 更多