【问题标题】:Elasticsearch multi field queryElasticsearch 多字段查询
【发布时间】:2016-08-18 19:06:49
【问题描述】:

我在 ElasticSearch 中构建地址搜索查询时遇到问题。

地址存储在 ES 中,结构如下:
地址 { 街道, 城市, 邮政编码 }

这是一个示例查询:

GET /adr-address/_search
{   
  "query": {
    "multi_match": {
      "query":       "mainstreet, houston",
      "type":        "most_fields",
      "fields":      [ "street", "city", "zipcode"]
    }
  }
}

"hits": [
 {
      "_source": {
       "id": "S6v4xyO8UE5NRcWtmMATPQ==",
       "street": "Houston 2nd Avenue",
       "zipcode": "8032",
       "city": "Houston"
    }
 },
 {
    "_source": {
       "id": "aLgQFrO8zCT8m88lAnYZPQ==",
       "street": "Houston 1st Avenue",
       "zipcode": "8044",
       "city": "Houston"
    }
 },
 {
    "_source": {
       "id": "aLgQFrO8zCT8m88lAnYZPQ==",
       "street": "mainstreet",
       "zipcode": "8044",
       "city": "Houston"
    }
 },

多匹配查询在大多数情况下都能正常工作,除了街道也包含城市名称的情况。 Elasticsearch 为这些结果分配了更高的优先级,这是完全可以理解的,即使不可接受。

这是_analyze结果:

GET /adr-address/_validate/query?explain
{
  "query": {
    "multi_match": {
      "query":       "mainstreet, houston",
      "type":        "most_fields",
      "fields":      [ "street", "city", "zipcode" ]
    }
  }
}

{
   "valid": true,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "explanations": [
      {
         "index": "adr-address",
         "valid": true,
         "explanation": "(zipcode:mainstreet zipcode:houston) (street:mainstreet street:houston) (city:mainstreet city:houston)"
      }
   ]
}

需要注意的是,google maps api 会针对同一个查询返回准确的结果。

到目前为止所做的假设/条件:

  1. 分词器有:空格、逗号、数字等
  2. 输入词可以包含多字街道名称、邮政编码或城市,顺序不限

关于如何改进搜索结果的任何建议?

【问题讨论】:

  • 我不知道,但你有没有试过改变顺序:[ "city", "zipcode", "street" ] ?
  • 是的,但它没有帮助,而且 _analyze 解释表明它搜索了两个字段中的所有术语
  • 我猜 copy_to 选项是我需要的。将所有值复制到一个新字段并在那里运行搜索。 elastic.co/guide/en/elasticsearch/guide/current/…我应该知道这是否可行。

标签: elasticsearch


【解决方案1】:

尝试使用 cross_fields 而不是 most_fields 作为 multi_match 的类型。

来自文档:

cross_fields 类型对结构化文档特别有用 多个字段应该匹配的地方。例如,当查询 “Will Smith”的名字和姓氏字段,最佳匹配是 可能在一个领域有“Will”,而在另一个领域有“Smith”。

您使用的 most_fields 似乎是用于搜索相同的文本,但以不同的方式进行分析。

查询示例:

GET /adr-address/_search
{   
  "query": {
    "multi_match": {
      "query":       "mainstreet, houston",
      "type":        "cross_fields",
      "fields":      [ "street", "city", "zipcode"]
    }
  }
}

link to docs

【讨论】:

  • 是的,这正是我现在正在尝试的,它看起来很有希望。明天完成后,我会将其标记为已接受的答案。
  • 完美运行!这是我的最终查询:GET /adr-address/_validate/query?explain { "query": { "multi_match": { "query": "mainstreet, houston", "type": "cross_fields", "minimum_should_match": 2, "fields": [ "street", "city", "zipcode", "state" ] } } }
猜你喜欢
  • 2022-12-04
  • 2015-03-08
  • 2020-02-26
  • 2022-06-29
  • 2021-05-03
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
相关资源
最近更新 更多