7

我有以下 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 查询需要如何更改才能仅在电子邮件上返回完全匹配。

4

1 回答 1

12

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

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

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

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

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

要克服这种行为,请声明电子邮件;字段为 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"
          }
        }
      }
    }
  }
}

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

于 2015-01-12T05:30:45.007 回答