匹配查询,并在字段中匹配多个单词

时间:2020-10-31 17:04:27

标签: elasticsearch match

如何在具有多个关键字匹配的字段(例如“洛杉矶”)上应用匹配查询,其中包含两个单词。如何从下面的数据结构中进行匹配

  "addresses" : [
        {
          "type" : "Home",
          "address" : "Los Angeles,CA,US"
        }
      ] 

下面是我的映射和设置,创建的自定义设置和过滤器

 PUT /test
 {
   "settings": {
     "analysis": {
       "filter" : {
             "my_word_delimiter" : {
                 "type" : "word_delimiter",
                 "type_table": [
                   "# => ALPHANUM",
                   "+ => ALPHANUM",
                   "@ => ALPHANUM",
                          "% => ALPHANUM",
                          "~ => ALPHANUM",
                          "^ => ALPHANUM",
                          "$ => ALPHANUM",
                          "& => ALPHANUM",
                          "' => ALPHANUM",
                          "\" => ALPHANUM",
                          "\/ => ALPHANUM",
                          ", => ALPHANUM"
                 ],
                 "preserve_original": "true",
                 "generate_word_parts":false,
                 "generate_number_parts":false,
                 "split_on_case_change":false,
                 "split_on_numerics":false,
                 "stem_english_possessive":false
             }   
         },
       "analyzer": {
             "default": {
                "type": "custom",
                "tokenizer": "whitespace",
                "filter": [
                   "lowercase",
                   "my_word_delimiter"
                ]
             }
          },
       "normalizer": {
         "keyword_lowercase": {
           "type": "custom",
           "filter": [
             "lowercase"
           ]
         }
       }
     }
   },
   "mappings": {
     "dynamic": "strict",
     "properties": {
      "addresses": {
         "type": "nested",
         "properties": {
           "address": {
             "type": "text"
           },
           "type": {
             "type": "keyword"
           }
         }
       }
     }
   }
 }

尝试以下查询,但未获得结果

 {
   "from": "0",
   "size": "30",
   "query": {
     "bool": {
       "must": [
         {
           "bool": {
             "should": [
               {
                 "nested": {
                   "path": "addresses",
                   "query": {
                     "match": {
                       "addresses.address": {
                         "query": "Los Angeles",
                         "operator": "and"
                       }
                     }
                   }
                 }
               }
             ]
           }
         }
       ]
     }
   },
   "sort": [
     {
       "_score": {
         "order": "desc"
       }
     }
   ]
 }

创建的设置是否有问题

1 个答案:

答案 0 :(得分:1)

由于地址使用的是"Los Angeles,CA,US"令牌生成器,因此如果地址的值类似于whitespace,则不会得到结果。

空白令牌生成器在遇到文本时会将其分解为术语 空格字符。

由于您在and查询中使用match运算符,因此该查询应检索同时具有LosAngeles的数据,但是由于空白标记器的原因,没有产生了Angeles的令牌,因此没有返回结果。

 POST/_analyze
    {
      "tokenizer": "whitespace",
      "text": "Los Angeles,CA,US"
    }

令牌为:

    {
  "tokens": [
    {
      "token": "Los",
      "start_offset": 0,
      "end_offset": 3,
      "type": "word",
      "position": 0
    },
    {
      "token": "Angeles,CA,US",
      "start_offset": 4,
      "end_offset": 17,
      "type": "word",
      "position": 1
    }
  ]
}

但是对于"Los Angeles ,CA,US",由于Angeles之后有一个空格,因此生成的令牌为:LosAngeles,CA,US < / p>

添加包含索引数据,映射和搜索结果的有效示例

索引映射:

除了从whitespace更改为"tokenizer":"standard"之外,保持映射不变

分析API

standard tokenizer提供了基于语法的标记化

{
  "tokenizer": "standard",
  "text": "Los Angeles ,CA,US"
}

令牌为:

{
  "tokens": [
    {
      "token": "Los",
      "start_offset": 0,
      "end_offset": 3,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "Angeles",
      "start_offset": 4,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "CA",
      "start_offset": 13,
      "end_offset": 15,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "US",
      "start_offset": 16,
      "end_offset": 18,
      "type": "<ALPHANUM>",
      "position": 3
    }
  ]
}

索引数据:

{
  "addresses": [
    {
      "type": "Home",
      "address": "Los Angeles,CA,US"
    }
  ]
}

使用与结果中相同的搜索查询

搜索结果:

"hits": [
      {
        "_index": "64624353",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.26706278,
        "_source": {
          "addresses": [
            {
              "type": "Home",
              "address": "Los Angeles,CA,US"
            }
          ]
        }
      }
    ]

注意:如果要使用whitespace标记生成器,然后从搜索查询中删除"operator": "and",将得到所需的结果

更新1:

尝试使用此更新的映射:

{
  "settings": {
    "analysis": {
      "filter": {
        "my_word_delimiter": {
          "type": "word_delimiter",
          "type_table": [
            "# => ALPHANUM",
            "+ => ALPHANUM",
            "@ => ALPHANUM",
            "% => ALPHANUM",
            "~ => ALPHANUM",
            "^ => ALPHANUM",
            "$ => ALPHANUM",
            "& => ALPHANUM",
            "' => ALPHANUM",
            "\" => ALPHANUM",
            "\/ => ALPHANUM"
          ],
          "preserve_original": "true",
          "generate_word_parts": true,
          "generate_number_parts": false,
          "split_on_case_change": false,
          "split_on_numerics": false,
          "stem_english_possessive": false
        }
      },
      "analyzer": {
        "default": {
          "type": "custom",
          "tokenizer": "whitespace",
          "filter": [
            "lowercase",
            "my_word_delimiter"
          ]
        }
      },
      "normalizer": {
        "keyword_lowercase": {
          "type": "custom",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  },
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "addresses": {
        "type": "nested",
        "properties": {
          "address": {
            "type": "text"
          },
          "type": {
            "type": "keyword"
          }
        }
      }
    }
  }
}
  1. generate_word_parts设置为true,以便过滤器在输出中包括由字母字符组成的标记。
  2. Word delimiter token filter,将令牌拆分为非字母数字字符。已从", => ALPHANUM"中删除type_table
相关问题