我想接受像“jan do”这样的查询,并让它匹配像“jane doe”、“don janek”这样的值——当然还有:“jan do”、“do jan”。
所以目前我能想到的规则是:
到目前为止,我有这个映射
PUT /test
{
"settings": {
"analysis": {
"analyzer": {
"my_keyword": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"asciifolding",
"lowercase"
]
}
}
}
},
"mappings": {
"question": {
"properties": {
"title": {
"type": "string"
},
"answer": {
"type": "object",
"properties": {
"text": {
"type": "string",
"analyzer": "my_keyword",
"fields": {
"stemmed": {
"type": "string",
"analyzer": "standard"
}
}
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在搜索词组:
POST /test/_search
{
"query": {
"dis_max": {
"tie_breaker": 0.7,
"boost": 1.2,
"queries": [
{
"match": {
"answer.text": {
"query": "jan do",
"type": "phrase_prefix"
}
}
},
{
"match": {
"answer.text.stemmed": {
"query": "jan do",
"operator": "and"
}
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
当事情真正开始该短语时,这可以正常工作,但现在我想标记查询并将每个标记视为前缀。
有没有办法做到这一点(可能在查询时)?
我的另一个选择是构建一个这样的查询:
POST test/_search
{
"query": {
"bool": {
"should": [
{
"prefix": {
"answer.text.stemmed": "jan"
}
},
{
"prefix": {
"answer.text.stemmed": "do"
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但它不保留单词的顺序。另外,我觉得那是作弊,可能不是性能最好的选择。如果有 10 个前缀呢?100?我想知道是否有人有不同的感觉。
正如上面的意见建议,你应该看一看的n-gram在Elasticsearch,尤其是边缘的n-gram。
我在这篇博文中为Qbox写了一篇关于使用ngrams 的介绍,但这里有一个你可以使用的快速示例。
这是一个索引定义,它将边缘 ngram 标记过滤器以及其他几个过滤器应用于自定义分析器(使用标准标记器)。
ES 2.0 中分析器的应用方式发生了一些变化。但是请注意,我用的是标准分析仪的"search_analyzer"。这是因为我不希望将搜索文本标记为 ngram,我希望它直接与索引标记匹配。有关详细信息的说明,请参阅博客文章。
无论如何,这是映射:
PUT /test_index
{
"settings": {
"analysis": {
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"standard",
"stop",
"kstem",
"edgengram_filter"
]
}
},
"filter": {
"edgengram_filter": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 15
}
}
}
},
"mappings": {
"doc": {
"properties": {
"name": {
"type": "string",
"analyzer": "autocomplete",
"search_analyzer": "standard"
},
"price":{
"type": "integer"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我索引了几个简单的文档:
POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"name": "very cool shoes","price": 26}
{"index":{"_id":2}}
{"name": "great shampoo","price": 15}
{"index":{"_id":3}}
{"name": "shirt","price": 25}
Run Code Online (Sandbox Code Playgroud)
现在,以下查询将为我提供预期的自动完成结果:
POST /test_index/_search
{
"query": {
"match": {
"name": {
"query": "ver sh",
"operator": "and"
}
}
}
}
...
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2169777,
"hits": [
{
"_index": "test_index",
"_type": "doc",
"_id": "1",
"_score": 0.2169777,
"_source": {
"name": "very cool shoes",
"price": 26
}
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
这是我在示例中使用的所有代码:
http://sense.qbox.io/gist/c2ba05900d0749fa3b1ba516c66431ae1a9d5e61
| 归档时间: |
|
| 查看次数: |
1120 次 |
| 最近记录: |