Elasticsearch Completion Suggester 不会 return 记录匹配输入的搜索

Elasticsearch Completion Suggester doesn't return documents on searches that match input

我在使用 Elasticsearch 6.0 时遇到了一个奇怪的问题。

我有一个具有以下映射的索引:

{
  "cities": {
    "mappings": {
      "cities": {
        "properties": {
          "city": {
            "properties": {
              "id": {
                "type": "long"
              },
              "name": {
                "properties": {
                  "en": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "it": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  }
                }
              },
              "slug": {
                "properties": {
                  "en": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "it": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  }
                }
              }
            }
          },
          "doctype": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "suggest": {
            "type": "completion",
            "analyzer": "accents",
            "search_analyzer": "simple",
            "preserve_separators": true,
            "preserve_position_increments": false,
            "max_input_length": 50
          },
          "weight": {
            "type": "long"
          }
        }
      }
    }
  }
}

我的索引中有这些文档:

{
  "_index": "cities",
  "_type": "cities",
  "_id": "991-city",
  "_version": 128,
  "found": true,
  "_source": {
    "doctype": "city",
    "suggest": {
      "input": [
        "nazaré",
        "nazare",
        "나자레",
        "najare",
        "najale",
        "ナザレ",
        "Ναζαρέ"
      ],
      "weight": 1807
    },
    "weight": 3012,
    "city": {
      "id": 991,
      "name": {
        "en": "Nazaré",
        "it": "Nazaré"
      },
      "slug": {
        "en": "nazare",
        "it": "nazare"
      }
    }
  }
}

{
  "_index": "cities",
  "_type": "cities",
  "_id": "1085-city",
  "_version": 128,
  "found": true,
  "_source": {
    "doctype": "city",
    "suggest": {
      "input": [
        "nazareth",
        "nazaret",
        "拿撒勒",
        "na sa le",
        "sa le",
        "le",
        "na-sa-lei",
        "나사렛",
        "nasares",
        "nasales",
        "ナザレス",
        "nazaresu",
        "नज़ारेथ",
        "nj'aareth",
        "aareth",
        "najaratha",
        "Назарет",
        "Ναζαρέτ",
        "názáret",
        "nazaretas"
      ],
      "weight": 1809
    },
    "weight": 3015,
    "city": {
      "id": 1085,
      "name": {
        "en": "Nazareth",
        "it": "Nazareth"
      },
      "slug": {
        "en": "nazareth",
        "it": "nazareth"
      }
    }
  }
}

现在,当我使用建议器进行搜索时,查询如下:

POST /cities/_search
{
  "suggest":{
    "suggest":{
      "prefix":"nazare",
      "completion":{
        "field":"suggest"
      }
    }
  }
}

我希望在我的结果中包含两个文件,但我只得到第二个(拿撒勒):

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": 0.0,
    "hits": []
  },
  "suggest": {
    "suggest": [
      {
        "text": "nazare",
        "offset": 0,
        "length": 6,
        "options": [
          {
            "text": "nazaresu",
            "_index": "cities",
            "_type": "cities",
            "_id": "1085-city",
            "_score": 1809.0,
            "_source": {
              "doctype": "city",
              "suggest": {
                "input": [
                  "nazareth",
                  "nazaret",
                  "拿撒勒",
                  "na sa le",
                  "sa le",
                  "le",
                  "na-sa-lei",
                  "나사렛",
                  "nasares",
                  "nasales",
                  "ナザレス",
                  "nazaresu",
                  "नज़ारेथ",
                  "nj'aareth",
                  "aareth",
                  "najaratha",
                  "Назарет",
                  "Ναζαρέτ",
                  "názáret",
                  "nazaretas"
                ],
                "weight": 1809
              },
              "weight": 3015,
              "city": {
                "id": 1085,
                "name": {
                  "en": "Nazareth",
                  "it": "Nazareth"
                },
                "slug": {
                  "en": "nazareth",
                  "it": "nazareth"
                }
              }
            }
          }
        ]
      }
    ]
  }
}

这是出乎意料的,因为在第一个文档的建议输入中,我搜索的术语 "nazare" 与我输入的完全一样。

另一个有趣的事实是,如果我搜索 "najare" 而不是 "nazare",我会得到正确的结果。

任何提示将不胜感激!

要获得快速解决方案,请在查询的 completion 对象中使用 size 参数。

GET /cities/_search
{
  "suggest":{
    "suggest":{
      "prefix":"nazare",
      "completion":{
        "field":"suggest",
        "size": 100             <- HERE
      }
    }
  }
}

大小参数默认为 5,因此一旦 elasticsearch 发现 5 个术语 (而不是文档)具有正确的前缀,它将停止寻找更多术语(以及相应的文档) ).

此限制是针对每个术语的,而不是针对每个文档的。因此,如果一个文档包含 5 个正确的术语,而您使用默认值 5,则可能不会返回其他文档。

我坚信这就是您的情况。返回的文档至少有 5 个前缀为 nazare 的建议术语,因此只会返回这个。

有趣的是,当您搜索 najare 时,只有一个字词具有正确的前缀,因此您得到了正确的结果。

棘手的是,结果取决于 elasticsearch 检索文档的顺序。如果第一个文档首先被检索到,它就不会达到 size 阈值(仅出现 2 或 3 个前缀),下一个文档也会被检索并且您会得到正确的结果。

此外,除非必要,否则请避免为 size 参数使用非常高的值(例如 > 1000)。它可能会影响性能,特别是对于短前缀或常见前缀。