我正在尝试为最终用户提供搜索类型,就像他们走的那样,这更像sqlserver。我能够为给定的SQL场景实现ES查询:
select * from table where name like '%peter tom%' and type != 'xyz
在ES中,我使用ngram tokenizer来达到预期的结果:
PUT sample
{
"settings": {
"analysis": {
"analyzer": {
"my_ngram_analyzer": {
"tokenizer": "my_ngram_tokenizer"
}
},
"tokenizer": {
"my_ngram_tokenizer": {
"type": "nGram",
"min_gram": "2",
"max_gram": "15"
}
}
}
},
"mappings": {
"typename": {
"properties": {
"name": {
"type": "string",
"fields": {
"search": {
"type": "string",
"analyzer": "my_ngram_analyzer"
}
}
},
"type": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
{
"query": {
"bool": {
"should": [
{
"term": {
"name.search": "peter tom"
}
}
],
"must_not": [
{
"match": {
"type": "xyz"
}
},
{
"match": {
"type": "abc"
}
}
]
}
}
}
所以,如果我的文档行像
name type
peter tomson efg
Peter tomson robert simson efg
上面的查询仅显示了两个文档,但是当我尝试输入Peter sims或Peter simson时,除非我输入Peter tomson robert sims或Peter tomson robert simson,否则它不会返回第二个文档。因此基本上我必须键入以下所有内容在彼得之后和西姆森之前的单词,到达第二个文档。有什么办法可以使第二个文档具有部分匹配。我可以使用查询匹配和“AND”操作,但是仍然与单词完全匹配。我正在寻找部分匹配,例如Peter sims应该给我第二行文件。
谢谢
最佳答案
我自己发布了解决方案供其他用户引用,从而找到了查询的答案:
{
"settings": {
"analysis": {
"analyzer": {
"autocomplete": {
"tokenizer": "whitespace",
"filter": [
"lowercase",
"autocomplete"
]
},
"autocomplete_search": {
"tokenizer": "whitespace",
"filter": [
"lowercase"
]
}
},
"filter": {
"autocomplete": {
"type": "nGram",
"min_gram": 2,
"max_gram": 40
}
}
}
},
"mappings": {
"doc": {
"properties": {
"title": {
"type": "string",
"analyzer": "autocomplete",
"search_analyzer": "autocomplete_search"
}
}
}
}
}
PUT my_index/doc/1
{
"title": "peter tomson"
}
PUT my_index/doc/2
{
"title": "Peter tomson robert simson"
}
GET my_index/doc/_search
{
"query": {
"match": {
"title": {
"query": "Pete sim",
"operator": "and"
}
}
}
}