我尝试在elasticsearch中实现搜索,该搜索应该在一个或多个字段中找到特定术语。术语可以由一个字母以及几个字母或几个单词组成。这个术语可以位于该领域的任何部分。它与SQL查询非常相似,其中的部分如下:
field1 like '%term%' or field2 like '%term%' or field3 like '%term%'
我可能有很多索引和许多类型,所以为了不为每个字段指定映射我决定使用动态模板。首先,我定义了分析部分
"analysis" : {
"filter" : {
"word_delimiter_filter" : {
"type" : "word_delimiter"
},
"ngram_filter" : {
"type" : "nGram",
"min_gram" : "1",
"max_gram" : "50"
}
},
"analyzer" : {
"custom_search_analyzer" : {
"filter" : [ "lowercase", "word_delimiter_filter" ],
"type" : "custom",
"tokenizer" : "standard"
},
"ngram_analyzer" : {
"filter" : [ "lowercase", "word_delimiter_filter", "ngram_filter" ],
"type" : "custom",
"tokenizer" : "standard"
}
}
}
它使我能够将一个可变长度的术语与该领域的任何部分相匹配:开头,中间或结尾以及整个单词。
我决定在 _all
字段中添加所有可搜索字段,并在此唯一字段中搜索字词。所以我的动态模板看起来像
{
"mappings": {
"my_type": {
"_all" : {
"analyzer" : "ngram_analyzer",
"search_analyzer" : "custom_search_analyzer"
},
"dynamic_templates" : [{
"searchable_fields": {
"match_mapping_type" : "string",
"match": "field1|field2|field3",
"match_pattern": "regex",
"mapping": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
},
"analyzer" : "ngram_analyzer",
"search_analyzer" : "standard",
"include_in_all": true
}
}
}]
}
}
}
当我在没有层次结构的情况下展平JSON时,它非常有用。当JSON与几个嵌套对象和对象数组相比复杂得多时,问题就出现了。在这些嵌套对象中,并非所有字段都是可搜索的,因此我需要指定要搜索的字段。我尝试了正则表达式匹配
"match": "nested_field1\\.field2|nested_field2.field1"
但这没有用。此外, path_match
和 path_unmatch
只接受一条路径。所以我想知道如何实现与几个嵌套对象字段的匹配,以便将它们添加到 _all
字段中进行搜索。
P.S。我也想知道这是一种有效的方法来实现具有此类要求的搜索,并匹配 _all
字段,或者使用 multi_match
查询?
简单的json看起来像
{
"storeId": "15",
"title": "London Store",
"address": "15 Green Street London",
"description": "Some description",
"phone": "Some phone",
"country": "UK",
"dateCreated": 1382444820000
}
更复杂的json
{
"orderId": "1",
"assistant": {
"id": "12",
"name": "John Doe"
},
"store": {
"id": "15",
"title": "London Store",
"address": "15 Green Street London"
},
"items": [{
"title": "Some Title",
"description": "Some description",
"attributes": {
"size": "L",
"colour": "black"
}
}],
"payments": [{
"paymentNumber": "SomeNumber",
"status": "Finished"
}]
}