【问题标题】:How to make query_string search exact phrase in ElasticSearch如何在 ElasticSearch 中使 query_string 搜索准确的短语
【发布时间】:2014-02-28 11:03:52
【问题描述】:

我在 Elasticsearch 中放了 2 个文档:

curl -XPUT "http://localhost:9200/vehicles/vehicle/1" -d'
{
    "model": "Classe A"
}'

curl -XPUT "http://localhost:9200/vehicles/vehicle/2" -d'
{
    "model": "Classe B"
}'

为什么这个查询会返回 2 个文档:

curl -XPOST "http://localhost:9200/vehicles/_search" -d'
{
  "query": {
    "query_string": {
      "query": "model:\"Classe A\""
    }
  }
}'

而这个,只有第二个文件:

curl -XPOST "http://localhost:9200/vehicles/_search" -d'
{
  "query": {
    "query_string": {
      "query": "model:\"Classe B\""
    }
  }
}'

我希望弹性搜索匹配我传递给查询参数的确切短语,带有空格,我该怎么做?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您需要查看的是您正在使用的analyzer。如果您不指定一个,Elasticsearch 将使用Standard Analyzer。它适用于大多数纯文本输入的情况,但不适用于您提到的用例。

    标准分析器会做的是拆分字符串中的单词,然后将它们转换为小写。

    如果要匹配整个字符串“Classe A”并将其与“Classe B”区分开来,可以使用Keyword Analyzer。这会将整个字段保留为一个字符串。

    然后你可以使用匹配查询,它会返回你期望的结果。

    创建映射:

    PUT vehicles
    {
      "mappings": {
        "vehicle": {
          "properties": {
            "model": {
              "type": "string",
              "analyzer": "keyword"
            }
          }
        }
      }
    }
    

    执行查询:

    POST vehicles/_search
    {
      "query": {
        "match": {
          "model": "Classe A"
        }
      }
    }
    

    如果您想使用query_string 查询,则可以将运算符设置为AND

    POST vehicles/vehicle/_search
    {
      "query": {
        "query_string": {
          "query": "Classe B",
          "default_operator": "AND"
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      此外,您可以使用 query_string 并转义引号也将返回一个确切的短语:

      POST _search
      {
          "query": {
            "query_string": {
              "query": "\"Classe A\""
           }
      }
      

      【讨论】:

      【解决方案3】:

      使用下面提到的匹配短语查询

      GET /company/employee/_search   
      {     
          "query" : {      
              "match_phrase" : {      
                  "about" : "rock climbing"      
              }      
          }      
      }
      

      【讨论】:

      • 此查询还返回“超级攀岩”、“攀岩和java”、任何包含“攀岩”的短语
      • @yaroslavTir 查询不返回字符串,它们返回匹配查询的文档。在这种情况下,所有这些文档都与短语查询“攀岩”匹配,因为它们包含该子字符串。
      【解决方案4】:

      似乎在最新版本的 ES 中你可以只使用 .keyword

      POST vehicles/_search
      {
        "query": {
          "term": {
            "model.keyword": "Classe A"
          }
        }
      }
      

      它将完全匹配字符串“Classe A”

      由 ES 确定为文本的动态字段将具有一个子字段“关键字”,对于这种情况非常有用: https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-field-mapping.html

      【讨论】:

        【解决方案5】:

        另一个不错的解决方案是使用matchminimum_should_match(提供您想要匹配的单词的百分比)。它可以是 100% 并且将返回至少包含给定文本的结果;

        重要的是,这种方法不考虑单词的顺序。

        "query":{
          "bool":{
             "should":[
                {
                   "match":{
                      "my_text":{
                         "query":"I want to buy a new new car",
                         "minimum_should_match":"90%"
                      }
                   }
                }
             ]
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2017-11-10
          • 1970-01-01
          • 2017-08-20
          • 1970-01-01
          • 1970-01-01
          • 2016-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多