我有一个弹性搜索5.3服务器与产品 . 每个产品都有一个14位数的产品代码,必须按照以下规则进行搜索 . 完整代码应与仅包含最后9位数字,最后6位数字,最后5位数字或最后4位数字的搜索词匹配 .
为了实现这一点,我创建了一个自定义分析器,它使用模式捕获令牌过滤器在索引时创建适当的标记 . 这似乎工作正常 . _analyse API显示正确的术语已创建 .
要从弹性搜索中获取文档,我正在使用multi_match cross_fields bool查询来同时搜索多个字段 .
当我的查询字符串具有与产品代码匹配的部分以及与任何其他字段匹配的部分时,不会返回任何结果,但是当我单独搜索每个部分时,将返回相应的结果 . 此外,当我有多个部分跨越除产品代码之外的任何字段时,将返回正确的结果 .
My maping and analyzer:
PUT /store
{
"mappings": {
"products":{
"properties":{
"productCode":{
"analyzer": "ProductCode",
"search_analyzer": "standard",
"type": "text"
},
"description": {
"type": "text"
},
"remarks": {
"type": "text"
}
}
}
},
"settings": {
"analysis": {
"filter": {
"ProductCodeNGram": {
"type": "pattern_capture",
"preserve_original": "true",
"patterns": [
"\\d{5}(\\d{9})",
"\\d{8}(\\d{6})",
"\\d{9}(\\d{5})",
"\\d{10}(\\d{4})"
]
}
},
"analyzer": {
"ProductCode": {
"filter": ["ProductCodeNGram"],
"type": "custom",
"preserve_original": "true",
"tokenizer": "standard"
}
}
}
}
}
The query
GET /store/products/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "[query_string]",
"fields": ["productCode", "description", "remarks"],
"type": "cross_fields",
"operator": "and"
}
}
]
}
}
}
Sample data
POST /store/products
{
"productCode": "999999123456789",
"description": "Foo bar",
"remarks": "Foobar"
}
以下查询字符串都返回一个结果:
“456789”,“foo”,“foobar”,“foo foobar” .
但query_string“foo 456789”不返回任何结果 .
我很好奇为什么最后一次搜索没有返回任何结果 . 我确信它应该 .
1 回答
问题是你在使用不同分析器的字段上进行交叉字段 . 交叉字段仅适用于使用相同分析器的字段 . 事实上,它在执行交叉字段之前通过分析器对字段进行分组 . 您可以在本文档中找到更多信息 .
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#_literal_cross_field_literal_and_analysis