我有一个关键字/关键短语字段我使用标准分析器进行标记。如果有一个搜索短语包含该字段的所有标记,我希望此字段匹配。
例如,如果字段值为" veni,vidi,vici"搜索短语是" Ceaser veni,vidi,vici"我希望这个搜索短语匹配,但搜索短语" veni,vidi"不匹配。
我还需要" vidi,veni,vici" (奇怪!)匹配。所以这些术语的位置和顺序并不重要。我认为短语匹配对我来说不太有用。
我可以使用" bool查询"使用" minimum_should_match"这个特定示例的参数,但实际上并不是我想要的最小值应匹配的是搜索短语中令牌的比率/数量。
答案 0 :(得分:2)
Pure ES解决方案就是这样的。您将需要两个请求。
1)首先,您需要通过analyze api传递用户查询以获取所有搜索令牌。
curl -XGET 'localhost:9200/_analyze' -d '
{
"analyzer" : "standard",
"text" : "Ceaser veni,vidi,vici"
}'
您将获得4个令牌 ceaser , veni , vidi , vici 。您需要将这些标记作为数组传递给下一个search
请求。
2)我们需要搜索代币为子集搜索令牌的文档。
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"query": {
"match": {
"title": "Ceaser veni,vidi,vici"
}
}
},
{
"script": {
"script": "if(search_tokens.containsAll(doc['title'].values)){return true;}",
"params": {
"search_tokens": [
"ceaser",
"veni",
"vidi",
"vici"
]
}
}
}
]
}
}
}
}
}
此处过滤器中第一个match query
的作业是缩小应运行脚本的文档的范围。 containsAll
方法将检查文档令牌是否为sublist
搜索令牌。这将是缓慢的,但将使用您当前的设置完成工作。您可以做的一个重大改进是将标记存储为数组,以便可以用该字段替换doc['title'].values
,这将改进脚本。
希望这有帮助!
答案 1 :(得分:0)
没有内置解决方案,但这有效:
在每个文档的字段中添加一个包含术语数的额外字段。所以在你的" veni,vidi,vici"例如,您将拥有类似" field_term_count"的字段。 :3。
对搜索查询中的每个标记执行单独匹配搜索。
将每个文档匹配的搜索次数与至少一个匹配项相加(例如,带有文档ID键和计数值的哈希表)。
将3中的匹配数与" field_term_count"进行比较每个匹配文档的字段。如果它们相等则文档就是匹配。
然后" Ceaser veni,vidi,vici"将匹配搜索短语" veni,vidi"不会,如所希望的那样。对于合理数量的匹配,它应该非常快。