大数据利器Elasticsearch搜索之多值字段match_phrase短语匹配查询

·  阅读 212

这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战
本Elasticsearch相关文章的版本为:2.3.1

当你对多值字段使用match_phrase短语匹配查询时会发生你意想不到的事。

测试数据:

POST /multi_value_match_pharse_test_index/_doc/1
{
  "followers": ["giselle chen", "vichen zhang"]
}
复制代码

对多值字段进行短语查询:

GET /multi_value_match_pharse_test_index/_doc/_search
{
  "query": {
    "match_phrase": {
      "followers": "chen vichen"
    }
  }
}
复制代码

返回的结果:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "multi_value_match_pharse_test_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "followers" : [
            "giselle chen",
            "vichen zhang"
          ]
        }
      }
    ]
  }
}
复制代码

出乎意料的是,尽管chen和vichen是出现在followers的两个关注者,但是也返回了这个文档。这是由于Elasticsearch在进行保存倒排索引的时候记录了以下的信息:
在分析giselle chen的时候:
position 1: giselle
poeition 2: chen

在分析vichen zhang的时候:
position 3: vichen
poeition 4: zhang

所以对chen vichen进行短语查询的时候,chen和zhang会被认为是相邻的(因为position 2和position 3是位置相邻的),所以匹配到了文档。

那么,在多值字段进行短语查询时需要是在同一个元素里面才认为是相邻的呢?
在这样的情况下,我们可以在字段映射中设置position_increment_gap参数来解决这个问题。
配置:

DELETE /multi_value_match_pharse_test_index/_doc

PUT /multi_value_match_pharse_test_index/_doc
{
    "properties": {
        "followers": {
            "type": "string",
            "position_increment_gap": 200
        }
    }
}
复制代码

position_increment_gap: 设置数组里面每个元素的下一个位置的增量。所以建议设置比单个关注者名字的分词个数要略大。

测试数据:

POST /multi_value_match_pharse_test_index/_doc/1
{
  "followers": ["giselle chen", "vichen zhang"]
}
复制代码

在设置了position_increment_gap=200后,上述文档的索引会变成这样:
在分析giselle chen的时候:
position 1: giselle
poeition 2: chen

在分析vichen zhang的时候:
position 203: vichen
poeition 204: zhang

所以对chen vichen进行短语查询的时候,chen和zhang就不会被认为是相邻的(因为position 2和position 203不是位置相邻的,相差200个间隔),所以不会匹配到文档。

分类:
后端
标签: