我想创建一个索引,其中包含一个名为“home_city”的字段。
我将需要在此索引上执行搜索,该索引返回所有带有home_city字段的文档,该字段正是“Little Rock”。
我还需要对该索引执行搜索,该搜索返回所有带有home_city字段的文档,该字段包含以查询字符串为前缀的任何单词。例如,如果查询字符串为“Ne”,则结果中将包含home_city =“New York”或home_city =“Long Neck”或home_city =“Nevinton”的文档。

我可以创建一个索引,该索引允许这两个查询中的任何一个,但不能两个都允许。

例如,如果我指示索引使用Elastic的“关键字”分析器,则前一个搜索(精确的完整关键字搜索)有效。我在创建这样的索引时指定了这个...

PUT my_index
{
   "mappings":{
       "properties":{
          "home_city": {
             "type":"text",
             "analyzer":"keyword",
         }
      }
   }
}

以下查询正确返回所有带有字段home_city =“Little Rock”的文档
{
  "query": {
    "bool": {
      "must": [
        {
              "query_string":{
                 "query":"Little Rock"
           }
        }]
     }
   }
}

同样,如预期的那样,如果查询不是完全是“Little Rock”,而是“Little”或“Rock”,则响应不包括带有home_city =“Little Rock”的文档。好,这就是我们想要的。

如果我使用默认设置创建索引,则后一种(前缀匹配)搜索有效。
查询看起来像这样...
{
  "query": {
            "match": {
                "home_city": "Di"
            }
      }
}

返回字段home_city =“San Diego”的文档和字段home_city =“Diamondville”的文档。

但是,我无法使这两个查询都在同一个索引上工作。如果在创建索引时指定了关键字分析器,并执行第二个查询(前缀匹配查询),则没有文档匹配。

我如何创建索引帽将与查找与整个查询字符串完全匹配的文档的查询以及查找包含该查询作为前缀的文档的查询一起使用。

最终,我们有兴趣将前缀匹配替换为更复杂的匹配,包括前缀匹配以及其他技术。但是现在,我们只想找出上述问题。

干杯。

最佳答案

您可以使用fields进行映射

制图

{
   "mappings":{
       "properties":{
          "home_city": {
             "type":"text",      --> will store as tokens using standard analyzer
             "fields": {
               "keyword":{
                 "type":"keyword" --> will store entire text as single token
               }
             }
         }
      }
   }
}

查询1:
GET index_10/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "Little Rock"
          }
        }
      ]
    }
  }
}

查询2:
使用match_phrase_prefix代替match_phrase

匹配词组
1.所有条款必须出现
2.他们必须有相同的顺序

Match_phrase_prefix


GET index_10/_search
{
  "query": {
    "match_phrase_prefix": {
      "home_city": "di"
    }
  }
}

要考虑的要点
  • 如果用户输入,最好使用simple_query_string而不是query_string,因为在搜索语法错误的情况下它不会引发错误。
  • Match_phrase_prefix将仅在 token 的开头搜索。如果需要在文本中的任何位置进行搜索,则可以浏览NGrams,EdgeNgrams以及内置的自动完成功能和search_as_you_type。
  • 10-08 09:06
    查看更多