Elasticsearch完成建议程序不会在与输入匹配的搜索中返回文档

时间:2019-07-16 09:12:56

标签: elasticsearch completion

我在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”,则会得到正确的结果。

任何提示将不胜感激!

1 个答案:

答案 0 :(得分:1)

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

completion

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

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

我坚信这是您的情况。返回的文档至少包含5个带有前缀GET /cities/_search { "suggest":{ "suggest":{ "prefix":"nazare", "completion":{ "field":"suggest", "size": 100 <- HERE } } } } 的建议字词,因此仅会返回该字词。

出于有趣的事实,当您搜索nazare时,只有一个词带有正确的前缀,因此您得到了正确的结果。

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

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