elasticsearch 如何使用Elasticsearch对文本输入执行部分单词搜索?
我有一个查询来搜索以下格式的记录:
elasticsearch 如何使用Elasticsearch对文本输入执行部分单词搜索?,
elasticsearch,nest,elasticsearch-6,
elasticsearch,Nest,Elasticsearch 6,我有一个查询来搜索以下格式的记录:TR000002\u 1\u 2020 用户应能够通过以下方式搜索结果: TR000002或2\u 1\u 2020或TR000002\u 1\u 2020或2020。我使用的是Elasticsearch 6.8,因此我无法使用E7中引入的内置搜索。因此,我认为通配符搜索或ngram可能最适合我的需要。以下是我的两种方法以及它们不起作用的原因 通配符 属性映射: .Text(t => t .Name(tr => tr.TestRecordId
TR000002\u 1\u 2020
用户应能够通过以下方式搜索结果:
TR000002
或2\u 1\u 2020
或TR000002\u 1\u 2020
或2020
。我使用的是Elasticsearch 6.8,因此我无法使用E7中引入的内置搜索。因此,我认为通配符
搜索或ngram
可能最适合我的需要。以下是我的两种方法以及它们不起作用的原因
.Text(t => t
.Name(tr => tr.TestRecordId)
)
查询:
m => m.Wildcard(w => w
.Field(tr => tr.TestRecordId)
.Value($"*{form.TestRecordId}*")
),
这是可行的,但它区分大小写,因此如果用户使用tr000002\u 1\u 2020
进行搜索,则不会返回任何结果(因为t
和r
在查询中是小写的)
.Analysis(a => a
.Analyzers(aa => aa
.Custom("autocomplete", ca => ca
.Tokenizer("autocomplete")
.Filters(new string[] {
"lowercase"
})
)
.Custom("autocomplete_search", ca => ca
.Tokenizer("lowercase")
)
)
.Tokenizers(t => t
.NGram("autocomplete", e => e
.MinGram(2)
.MaxGram(16)
.TokenChars(new TokenChar[] {
TokenChar.Letter,
TokenChar.Digit,
TokenChar.Punctuation,
TokenChar.Symbol
})
)
)
)
属性映射
.Text(t => t
.Name(tr => tr.TestRecordId)
.Analyzer("autocomplete")
.SearchAnalyzer("autocomplete_search")
)
质疑
如上所述,这不起作用,因为标记器将字符拆分为元素,如20
和02
和2020
,因此我的查询返回了我索引中包含2020的所有文档,如TR000002\u 1\u 2020
和tr00008\u 1\u 2020
和tr00003\u 6\u 2020
Elasticsearch的最佳用途是什么,以允许我进行所需的搜索行为?我还看到使用了
查询字符串
。谢谢 这里有一个简单的方法来满足您的需求(我希望如此)
TR000002_1_2020
我们得到了令牌[“2”、“1”、“2020”]
。因此,它将匹配查询[“TR000002\u 1\u 2020”、“TR000002 1 2020”、“2\u 1\u 2020”、“1\u 2020”]
,但不会匹配3\u 1\u 2020
或2\u 2020
下面是一个映射和分析的示例。它不在巢里,但我想你能翻译出来
PUT pattern_split_demo
{
"settings": {
"analysis": {
"char_filter": {
"replace_char_filter": {
"type": "pattern_replace",
"pattern": "^TR0*",
"replacement": ""
}
},
"tokenizer": {
"split_tokenizer": {
"type": "simple_pattern_split",
"pattern": "_"
}
},
"analyzer": {
"split_analyzer": {
"tokenizer": "split_tokenizer",
"filter": [
"lowercase"
],
"char_filter": [
"replace_char_filter"
]
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "split_analyzer"
}
}
}
}
POST pattern_split_demo/_analyze
{
"text": "TR000002_1_2020",
"analyzer": "split_analyzer"
} => ["2", "1", "2020"]
POST pattern_split_demo/_doc?refresh=true
{
"content": "TR000002_1_2020"
}
POST pattern_split_demo/_search
{
"query": {
"match_phrase": {
"content": "TR000002_1_2020"
}
}
}
格式
TR000002_1_2020
是否有一些通用模式,即可以从正则表达式中辨别出来的模式?@RussCam-hmm因此,该字符串中唯一一致的部分是TR
。000002
会增加(它被称为测试记录编号),u1
是任务编号,因此会发生变化,2020
是年份,因此也会明显增加,所以像TR\d+\ud+\ud+
这样的模式会起作用吗?我认为模式标记器与木瓦和小写标记过滤器相结合可能是一种有效的方法
PUT pattern_split_demo
{
"settings": {
"analysis": {
"char_filter": {
"replace_char_filter": {
"type": "pattern_replace",
"pattern": "^TR0*",
"replacement": ""
}
},
"tokenizer": {
"split_tokenizer": {
"type": "simple_pattern_split",
"pattern": "_"
}
},
"analyzer": {
"split_analyzer": {
"tokenizer": "split_tokenizer",
"filter": [
"lowercase"
],
"char_filter": [
"replace_char_filter"
]
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "split_analyzer"
}
}
}
}
POST pattern_split_demo/_analyze
{
"text": "TR000002_1_2020",
"analyzer": "split_analyzer"
} => ["2", "1", "2020"]
POST pattern_split_demo/_doc?refresh=true
{
"content": "TR000002_1_2020"
}
POST pattern_split_demo/_search
{
"query": {
"match_phrase": {
"content": "TR000002_1_2020"
}
}
}