具有变量值的 ElasticSearch 搜索结果

ElasticSearch search results with variable values

我希望将 elasticsearch 用于具有自动完成功能的搜索栏。 我有一组问题,它们有多个变量,我想用其他值代替。

一个问题的模板是:你喜欢 FIELDS 吗? FIELDS 被数学、物理、历史取代 然后在查询“do you like”这个问题时,它会显示多个匹配项:

我将 elasticseach 视为同义词分析器,并认为它可以用于此用例,但它似乎不像我预期的那样工作。下面是我目前所拥有的。

创建索引

{
        "mappings": {
            "properties": {
                "my_field": {
                    "type": "search_as_you_type",
                    "analyzer": "standard",
                    "search_analyzer": "synonym_analyzer"
                }
            }
        },
        "settings": {
            "index": {
                "analysis": {
                    "analyzer": {
                        "synonym_analyzer": {
                            "tokenizer": "whitespace",
                            "filter": ["my_synonyms"]
                        }
                    },
                    "filter": {
                        "my_synonyms": {
                            "type": "synonym",
                            "synonyms": [
                                "FIELDS => math, physics, history"
                            ]
                        }
                    }
                }
            }
        }
    }

查询

{
        "query": {
            "multi_match": {
                "query": partial_question,
                "type": "bool_prefix",
                "fields": [
                    "my_field",
                    "my_field._2gram",
                    "my_field._3gram",
                    "my_field._index_prefix"
                ]
            }
        }
    }

结果是一个结果“你喜欢 FIELDS 吗?”

我认为你用同义词看错方向了。 你要的是一个suggester。 您将需要做一些具体的工作,但您将能够为您的用例创建非常强大的建议。

如果我很好地理解了你的问题,我做了一个你可以使用的建议答案。我使用通配符查询和规范化器来小写所有值:

这是我的索引的映射:

PUT multiple-fields
{
  "settings": {
    "analysis": {
      "normalizer": {
        "lowercase_normalizer": {
          "type":"custom",
        "filter": ["lowercase"]
        }
        
      }
    }
  },
  "mappings": {
    "properties": {
      "quest":{
        "type": "keyword",
        "normalizer": "lowercase_normalizer"
      }
    }
  }
}

我在索引中提取了以下数据:

"quest":"你喜欢数学吗?"

"quest":"你喜欢物理吗?"

"quest":"你喜欢历史吗?"

"quest":"我想我喜欢你"

"quest":"我喜欢红色的车"

"quest":"你不喜欢吗"

"quest":"你喜欢数学吗?"

根据这些值,我创建了以下查询:

GET multiple-fields/_search
{
  "query": {
    "wildcard": {
      "quest": {
        "value": "do you like*"
      }
    }
  }
}

回复是:

"hits" : [
  {
    "_index" : "multiple-fields",
    "_type" : "_doc",
    "_id" : "bue1e3QBsTCl1BZvB0by",
    "_score" : 1.0,
    "_source" : {
      "quest" : "do you like math?"
    }
  },
  {
    "_index" : "multiple-fields",
    "_type" : "_doc",
    "_id" : "cOe1e3QBsTCl1BZvD0Yh",
    "_score" : 1.0,
    "_source" : {
      "quest" : "do you like physics?"
    }
  },
  {
    "_index" : "multiple-fields",
    "_type" : "_doc",
    "_id" : "cee1e3QBsTCl1BZvE0Zq",
    "_score" : 1.0,
    "_source" : {
      "quest" : "do you like history?"
    }
  },
  {
    "_index" : "multiple-fields",
    "_type" : "_doc",
    "_id" : "2-e1e3QBsTCl1BZvLUak",
    "_score" : 1.0,
    "_source" : {
      "quest" : "Do you like math?"
    }
  }
]

链接: https://www.elastic.co/guide/en/elasticsearch/reference/current/normalizer.html https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html

注意:但是,如果您使用通配符,可能会影响性能

如果对您有帮助,请告诉我,否则我们可以研究其他解决方案,谢谢。

@hansley 的答案可行,但由于通配符查询的成本很高,您可以简单地使用 prefix query 而无需更改索引中的任何内容。

虽然有多种方法可以在 ES 中实现 Autosuggest,并且考虑到它的重要性和受欢迎程度,我写了一篇 detailed blog on various approaches and their trade-off Also my 可以为您提供有关构建 Autosuggest 功能的功能和 non-function 要求的信息。

使用前缀查询的端到端示例:

默认索引映射,为每个文本字段创建一个 .keyword field

索引示例文档:

{
  "title" : "i like red car"
}

{
  "title" : "do you like math?"
}

{
  "title" : "do you like physics?"
}

搜索查询

{
  "query": {
    "prefix": {
      "title.keyword": {
        "value": "do you like"
      }
    }
  }
}

搜索结果

"hits": [
      {
        "_index": "partialpre",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "title": "do you like math?"
        }
      },
      {
        "_index": "partialpre",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "title": "do you like physics?"
        }
      }
    ]