假设我有两个包含以下信息的"catField“文档:
第一份文件:
happy cat
sad cat
meh cat
第二份文件:
happy cat
happy cat
happy cat
我试图编写一个满足两个要求的查询:
下面是我的初始解决方案,它使用span_near
和regexp来满足第一个需求:
"span_near": {
"clauses": [
{
"span_multi": {
"match": {
"regexp": {
"catField": "[a-z]{3,}"
}
}
}
},
{
"span_multi": {
"match": {
"regexp": {
"catField": "cat"
}
}
}
}
],
"slop": 0,
"in_order": true
}
这对于查找带有猫列表的文档非常有用,但它将对文档一进行排序,而文档二(上图)则是相同的。我如何才能满足第二个要求,排名唯一的猫名单高于非唯一的?
发布于 2013-12-07 09:09:19
因此,这里有一种方法,使用一些索引魔术,以获得您想要的。我不完全确定您的需求(因为您可能处理的数据比“愉快的猫”更复杂),但是它应该让您从索引时间的方向开始。
这可能是正确的方法,也可能不是您的设置。根据索引大小和查询负载,短语查询/span查询/bool组合可能工作得更好。但是,您的需求是很棘手的,因为它们取决于顺序、前面令牌的大小和变化的数量。
这样做的优点是,您的许多复杂逻辑都被放入索引中,从而在查询时获得了速度。然而,它确实会使您的数据变得更加僵化。
curl -XDELETE localhost:9200/cats
curl -XPUT localhost:9200/cats -d '
{
"settings" : {
"number_of_shards" : 1,
"number_of_replicas" : 0,
"index" : {
"analysis" : {
"analyzer" : {
"catalyzer" : {
"type" : "custom",
"tokenizer" : "keyword",
"filter" : ["cat_pattern", "unique", "cat_replace"]
}
},
"filter" : {
"cat_pattern" : {
"type" : "pattern_capture",
"preserve_original" : false,
"patterns" : [
"([a-z]{3,} cat)"
]
},
"cat_replace" : {
"type" : "pattern_replace",
"preserve_original" : false,
"pattern" : "([a-z]{3,} cat)",
"replacement" : "cat"
}
}
}
}
},
"mappings" : {
"cats" : {
"properties" : {
"catField" : {
"type" : "multi_field",
"fields": {
"catField" : {
"type": "string",
"analyzer": "standard"
},
"catalyzed" : {
"type": "string",
"index_analyzer": "catalyzer",
"search_analyzer" : "whitespace"
}
}
}
}
}
}
}'
首先,我们正在创建一个包含大量自定义分析的索引。首先,我们使用关键字分析器进行标记(它实际上并不是标记,只是发出一个令牌)。然后,我们使用一个pattern_capture
过滤器查找所有“猫”前面有一个字长于三个字符。然后,我们使用一个unique
过滤器来去除重复的(例如,连续三次“快乐猫”)。最后,我们使用一个pattern_replace
将我们的“快乐猫”变成了“猫”。
字段的最后标记将只是"cat",但是如果有多种类型的猫,则会出现更多的"cat“。
在搜索的时候,我们只需搜索"cat“,经常提到"cat”的文档就会被推高。由于我们的分析,更多的提及意味着更多独特的类型,因此我们得到了“免费”的助推行为。
我使用了一个多字段,所以您仍然可以查询原始字段(例如,如果您想搜索“愉快的猫”)。
使用上述映射进行演示:
curl -XPOST localhost:9200/cats/cats/1 -d '
{
"catField" : ["sad cat", "happy cat", "meh cat"]
}'
curl -XPOST localhost:9200/cats/cats/2 -d '
{
"catField" : ["happy cat", "happy cat", "happy cat"]
}'
curl -XPOST localhost:9200/cats/cats/3 -d '
{
"catField" : ["a cat", "x cat", "y cat"]
}'
curl -XPOST localhost:9200/cats/cats/_search -d '
{
"query" : {
"match": {
"catField.catalyzed": "cat"
}
}
}'
注意,搜索不会返回第三个文档,因为它的前面没有一个类型超过三个字符的cat。
https://stackoverflow.com/questions/20434161
复制相似问题