elasticsearch 同义词分析器给出 0 个结果

elasticsearch synonyms analyzer gives 0 results

我正在使用 elasticsearch 7.0.0

我在创建 index 时尝试使用此配置处理 synonyms

{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "synonym": {
            "tokenizer": "whitespace",
            "filter": [
              "synonym"
            ]
          }
        },
        "filter": {
          "synonym": {
            "type": "synonym",
            "synonyms_path": "synonyms.txt"
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "address.state": {
        "type": "text",
        "analyzer": "synonym"
      },
      "location": {
        "type": "geo_point"
      }
    }
  }
}

这是插入索引的文档:

{
  "name": "Berry's Burritos",
  "description": "Best burritos in New York",
  "address": {
    "street": "230 W 4th St",
    "city": "New York",
    "state": "NY",
    "zip": "10014"
  },
  "location": [
    40.7543385,
    -73.976313
  ],
  "tags": [
    "mexican",
    "tacos",
    "burritos"
  ],
  "rating": "4.3"
}

还有synonyms.txt中的内容:

ny, new york, big apple

当我尝试在 address.state 属性 中搜索任何内容时,我得到了 empty 个结果。

查询如下:

{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "rating": {
            "gte": 4
          }
        }
      },
      "must": {
        "match": {
          "address.state": "ny"
        }
      }
    }
  }
}

即使用ny(作为is:no的同义词)查询,结果也是空的。

之前,当我在没有 mappings 的情况下创建索引时,查询用于给出结果,仅同义词除外。

但现在使用 mappings,即使该术语存在,结果也是空的。

虽然此查询有效: { "query":{ "query_string":{ "query": "tacos", "fields": [ "tags" ] } } }

我查看并研究了许多 articles/tutorials 并得出了这个结论。

我现在在这里缺少什么?

在编制索引时,您将值作为 "state":"NY" 传递。注意 NY 的情况。设置中定义的分析器 synonym 只有一个过滤器,即 synonym。由于大小写原因,NY 与 synonym.txt 中定义的任何同义词集都不匹配。注意 NY 不等于 ny。为了克服这个问题(或者我们可以称之为不区分大小写)在 synonym 过滤器之前添加 lowercase 过滤器到 synonym 分析器。这将确保首先将任何输入文本小写,然后应用同义词过滤器。当您使用全文搜索查询在该字段上搜索时,也会发生同样的情况。

所以你的设置如下:

  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "synonym": {
            "tokenizer": "whitespace",
            "filter": [
              "lowercase",
              "synonym"
            ]
          }
        },
        "filter": {
          "synonym": {
            "type": "synonym",
            "synonyms_path": "synonyms.txt"
          }
        }
      }
    }
  }

映射中不需要更改。

为什么最初有效?

答案是因为当您没有定义任何映射时,elastic 会将 address.state 映射为 text 字段,而没有为该字段定义明确的分析器。在这种情况下,elasticsearch 默认使用 standard analyzer,它使用小写标记过滤器作为过滤器之一。因此查询与文档匹配。