为什么ElasticSearch匹配查询返回所有结果?

时间:2015-01-12 04:13:57

标签: node.js elasticsearch elasticsearch-plugin

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

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

}

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

    {
      "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查询以便仅返回电子邮件上的完全匹配。

1 个答案:

答案 0 :(得分:9)

电子邮件字段已被标记化,这是此异常的原因。 所以当你编入索引时发生了什么

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

这样,如果您搜索myemail或gmail.com,您将获得正确的匹配。 所以当你搜索john@gmail.com时,分析器也应用于搜索查询。 因此它被打破了

" john@gmail.com" => ["约翰" ," 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