作者:来自 Elastic Kathleen DeRusso
查询规则(query rules)允许使用细粒度、上下文特定的解决方案来更改特定查询或搜索用例的搜索结果。这对于需要将品牌或赞助结果固定在特定关键字的搜索结果列表顶部的广告系列很有帮助,但对于只需要 “修复” 顶部结果的热门查询也很有帮助。
简介
我们很高兴地宣布,查询规则已在我们的 serverless 产品中正式发布,并且将从堆栈版本 8.15.0 开始普遍可用。查询规则最初在 8.10.0 中作为技术预览功能引入,并允许索引维护者根据上下文查询输入的条件整理特定文档以将其固定在结果顶部。
查询规则如何工作?
查询规则是你根据特定查询元数据定义的规则。首先,你需要定义一个查询规则集,该规则集会识别要针对查询中发送的某些元数据进行推广的文档。然后在搜索时,你将该元数据与规则查询一起发送。如果规则查询中发送的元数据与任何规则匹配,则这些规则将应用于你的结果集。
新的查询规则功能
我们在向正式版迈进的过程中为查询规则添加了一些功能。
这些变化的简要概述:
- 我们将规则查询从 rule_query 重命名为rule,以与我们的其他API调用更加一致
- 我们现在支持在单个规则查询中指定多个规则集
- 我们扩展了 query ruleset management APIs 以支持管理单个查询规则
这是什么样子的?
假设我们有一个包含狗品种信息的索引,其中包含两个字段:dog_breed 和 advert。我们想要设置规则,将品种和混合品种固定在同一个规则中。这是一个包含两个规则的示例规则集:
PUT _query_rules/dog-breed-ruleset
{
"ruleset_id": "dog-breed-ruleset",
"rules": [
{
"rule_id": "pug-mixes",
"type": "pinned",
"criteria": [
{
"type": "exact",
"metadata": "breed",
"values": [
"pug"
]
}
],
"actions": {
"ids": [
"pug",
"puggle",
"chug",
"pugshire"
]
},
"priority": 5
},
{
"rule_id": "chi-mixes",
"type": "pinned",
"criteria": [
{
"type": "exact",
"metadata": "breed",
"values": [
"chihauhua"
]
}
],
"actions": {
"ids": [
"chihauhua",
"chiweenie",
"chug"
]
},
"priority": 10
}
]
}
解析此规则集的作用:
- 如果规则查询发送品种:pug,则按顺序显示的第一个结果将是:pug、puggle、chug 和 pugshire。任何自然结果都将在这些固定结果之后返回。
- 如果规则查询发送品种:chihuahua,则按顺序显示的第一个结果将是:chihuahua、chiweenie 和 chug。任何自然结果都将在这些固定结果之后返回。
需要注意的一点是规则集中每个规则的优先级。这是每个规则的可选部分,但它可以帮助你定义单个规则插入规则集的位置。规则集按优先级升序排序,但正如你在此示例中所见,它们不必连续。将优先级为 4 或更低的新规则插入此规则集会将新规则插入规则集的开头,而优先级介于 6 和 9 之间会将新规则插入规则集中间两个现有规则之间。如果将单个规则添加到规则集中但不包含优先级,则它将被简单地附加到规则集的末尾。
查询规则的另一个有用功能是我们现在支持将多个规则集传递到规则查询中。这允许你组织和定义更多规则;以前,你只能在单个规则集中容纳有限的规则数量(默认情况下为 100 条,或可配置为每个规则集最多 1000 条)。
让我们通过专门为 7 月促销活动创建一个新规则集来看看它是什么样子。此规则的类型为 “always”,因此无论如何它都会始终返回:
PUT _query_rules/promo-ruleset
{
"rules": [
{
"rule_id": "july-promo",
"type": "pinned",
"criteria": [
{
"type": "always"
}
],
"actions": {
"ids": [
"july-promotion"
]
}
}
]
}
现在,我们可以使用以下查询一起查询这些规则集:
GET query-rules-test/_search
{
"query": {
"rule": {
"organic": {
"query_string": {
"query": "chihauhua mixes"
}
},
"ruleset_ids": [
"promo-ruleset",
"dog-breed-ruleset"
],
"match_criteria": {
"breed": "chihauhua"
}
}
}
}
由于指定了两个规则集,我们将按照请求中指定的顺序处理每个规则集。这意味着七月促销规则将始终作为第一个结果返回,匹配的狗品种将随后被置顶,结果如下所示:
"hits": [
{
"_index": "query-rules-test",
"_id": "july-promotion",
"_score": 1.7014128e+38,
"_source": {
"advert": "EVERYTHING ON SALE!"
}
},
{
"_index": "query-rules-test",
"_id": "chihauhua",
"_score": 1.7014126e+38,
"_source": {
"dog_breed": "chihauhua"
}
},
{
"_index": "query-rules-test",
"_id": "chiweenie",
"_score": 1.7014124e+38,
"_source": {
"dog_breed": "chiweenie"
}
},
{
"_index": "query-rules-test",
"_id": "chug",
"_score": 1.7014122e+38,
"_source": {
"dog_breed": "chug"
}
},
... // organic results follow...
]
这些都是简单的例子,那么一些更复杂的例子呢?
我们可以提供帮助!
让我们继续我们的狗主题,但扩展测试索引中的映射:
PUT query-rules-test
{
"mappings": {
"properties": {
"breed": {
"type": "keyword"
},
"age": {
"type": "integer"
},
"sex": {
"type": "keyword"
},
"name": {
"type": "keyword"
},
"bio": {
"type": "text"
},
"good_with_animals": {
"type": "boolean"
},
"good_with_kids": {
"type": "boolean"
}
}
}
}
我们可以将以下 json 索引到此索引中以获取一些示例数据。为了保持一致性,我们假设 _id 字段与 json id 字段匹配:
[
{"id":"buddy_pug","breed":"pug","sex":"Male","age":3,"name":"Buddy","bio":"Buddy is a charming pug who loves to play and snuggle. He is looking for a loving home.","good_with_animals":true,"good_with_kids":true},
{"id":"lucy_beagle","breed":"beagle","sex":"Female","age":7,"name":"Lucy","bio":"Lucy is a friendly beagle who enjoys long walks and is very affectionate.","good_with_animals":true,"good_with_kids":true},
{"id":"rocky_chihuahua","breed":"chihuahua","sex":"Male","age":2,"name":"Rocky","bio":"Rocky is a tiny chihuahua with a big personality. He is very playful and loves attention.","good_with_animals":false,"good_with_kids":false},
{"id":"zoe_dachshund","breed":"dachshund","sex":"Female","age":5,"name":"Zoe","bio":"Zoe is a sweet dachshund who loves to burrow under blankets and is very loyal.","good_with_animals":true,"good_with_kids":true},
{"id":"max_poodle","breed":"poodle","sex":"Male","age":6,"name":"Max","bio":"Max is a smart and active poodle who loves learning new tricks and is very friendly.","good_with_animals":true,"good_with_kids":true},
{"id":"bella_yorkie","breed":"yorkie","sex":"Female","age":4,"name":"Bella","bio":"Bella is a cute yorkie who loves to be pampered and is very affectionate.","good_with_animals":true,"good_with_kids":true},
{"id":"jack_puggle","breed":"puggle","sex":"Male","age":8,"name":"Jack","bio":"Jack is a friendly puggle who loves to play and is very social.","good_with_animals":true,"good_with_kids":true},
{"id":"lola_chiweenie","breed":"chiweenie","sex":"Female","age":9,"name":"Lola","bio":"Lola is a playful chiweenie who loves to chase toys and is very affectionate.","good_with_animals":true,"good_with_kids":true},
{"id":"charlie_chug","breed":"chug","sex":"Male","age":3,"name":"Charlie","bio":"Charlie is an energetic chug who loves to play and is very curious.","good_with_animals":false,"good_with_kids":true},
{"id":"daisy_pugshire","breed":"pugshire","sex":"Female","age":7,"name":"Daisy","bio":"Daisy is a gentle pugshire who loves to cuddle and is very sweet.","good_with_animals":true,"good_with_kids":true},
{"id":"buster_pug","breed":"pug","sex":"Male","age":10,"name":"Buster","bio":"Buster is a calm pug who loves to lounge around and is very loyal.","good_with_animals":true,"good_with_kids":true},
{"id":"molly_beagle","breed":"beagle","sex":"Female","age":12,"name":"Molly","bio":"Molly is a sweet beagle who loves to sniff around and is very friendly.","good_with_animals":true,"good_with_kids":true},
{"id":"toby_chihuahua","breed":"chihuahua","sex":"Male","age":4,"name":"Toby","bio":"Toby is a lively chihuahua who loves to run around and is very playful.","good_with_animals":false,"good_with_kids":false},
{"id":"luna_dachshund","breed":"dachshund","sex":"Female","age":1,"name":"Luna","bio":"Luna is a young dachshund who loves to explore and is very curious.","good_with_animals":true,"good_with_kids":true},
{"id":"oliver_poodle","breed":"poodle","sex":"Male","age":17,"name":"Oliver","bio":"Oliver is a wise poodle who loves to relax and is very gentle.","good_with_animals":true,"good_with_kids":true}]
我们使用如下的方法进行写入:
PUT _bulk
{"index":{"_index":"query-rules-test","_id":"buddy_pug"}}
{"id":"buddy_pug","breed":"pug","sex":"Male","age":3,"name":"Buddy","bio":"Buddy is a charming pug who loves to play and snuggle. He is looking for a loving home.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"lucy_beagle"}}
{"id":"lucy_beagle","breed":"beagle","sex":"Female","age":7,"name":"Lucy","bio":"Lucy is a friendly beagle who enjoys long walks and is very affectionate.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"rocky_chihuahua"}}
{"id":"rocky_chihuahua","breed":"chihuahua","sex":"Male","age":2,"name":"Rocky","bio":"Rocky is a tiny chihuahua with a big personality. He is very playful and loves attention.","good_with_animals":false,"good_with_kids":false}
{"index":{"_index":"query-rules-test","_id":"zoe_dachshund"}}
{"id":"zoe_dachshund","breed":"dachshund","sex":"Female","age":5,"name":"Zoe","bio":"Zoe is a sweet dachshund who loves to burrow under blankets and is very loyal.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"max_poodle"}}
{"id":"max_poodle","breed":"poodle","sex":"Male","age":6,"name":"Max","bio":"Max is a smart and active poodle who loves learning new tricks and is very friendly.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"bella_yorkie"}}
{"id":"bella_yorkie","breed":"yorkie","sex":"Female","age":4,"name":"Bella","bio":"Bella is a cute yorkie who loves to be pampered and is very affectionate.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"jack_puggle"}}
{"id":"jack_puggle","breed":"puggle","sex":"Male","age":8,"name":"Jack","bio":"Jack is a friendly puggle who loves to play and is very social.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"lola_chiweenie"}}
{"id":"lola_chiweenie","breed":"chiweenie","sex":"Female","age":9,"name":"Lola","bio":"Lola is a playful chiweenie who loves to chase toys and is very affectionate.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"charlie_chug"}}
{"id":"charlie_chug","breed":"chug","sex":"Male","age":3,"name":"Charlie","bio":"Charlie is an energetic chug who loves to play and is very curious.","good_with_animals":false,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"daisy_pugshire"}}
{"id":"daisy_pugshire","breed":"pugshire","sex":"Female","age":7,"name":"Daisy","bio":"Daisy is a gentle pugshire who loves to cuddle and is very sweet.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"buster_pug"}}
{"id":"buster_pug","breed":"pug","sex":"Male","age":10,"name":"Buster","bio":"Buster is a calm pug who loves to lounge around and is very loyal.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"molly_beagle"}}
{"id":"molly_beagle","breed":"beagle","sex":"Female","age":12,"name":"Molly","bio":"Molly is a sweet beagle who loves to sniff around and is very friendly.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"toby_chihuahua"}}
{"id":"toby_chihuahua","breed":"chihuahua","sex":"Male","age":4,"name":"Toby","bio":"Toby is a lively chihuahua who loves to run around and is very playful.","good_with_animals":false,"good_with_kids":false}
{"index":{"_index":"query-rules-test","_id":"luna_dachshund"}}
{"id":"luna_dachshund","breed":"dachshund","sex":"Female","age":1,"name":"Luna","bio":"Luna is a young dachshund who loves to explore and is very curious.","good_with_animals":true,"good_with_kids":true}
{"index":{"_index":"query-rules-test","_id":"oliver_poodle"}}
{"id":"oliver_poodle","breed":"poodle","sex":"Male","age":17,"name":"Oliver","bio":"Oliver is a wise poodle who loves to relax and is very gentle.","good_with_animals":true,"good_with_kids":true}
接下来,让我们创建一个规则集:
PUT _query_rules/rescue-dog-search-ruleset
{
"rules": [
{
"rule_id": "pugs_and_pug_mixes",
"type": "pinned",
"criteria": [
{
"type": "contains",
"metadata": "query_string",
"values": [
"pug"
]
}
],
"actions": {
"ids": [
"buddy_pug",
"buster_pug",
"jack_puggle",
"daisy_pugshire"
]
}
},
{
"rule_id": "puppies",
"type": "pinned",
"criteria": [
{
"type": "contains",
"metadata": "query_string",
"values": [
"puppy",
"puppies"
]
}
],
"actions": {
"ids": [
"luna_dachsund"
]
}
},
{
"rule_id": "puppies2",
"type": "pinned",
"criteria": [
{
"type": "lte",
"metadata": "preferred_age",
"values": [
2
]
}
],
"actions": {
"ids": [
"luna_dachshund"
]
}
},
{
"rule_id": "adult",
"type": "pinned",
"criteria": [
{
"type": "gt",
"metadata": "preferred_age",
"values": [
2
]
},
{
"type": "lt",
"metadata": "preferred_age",
"values": [
10
]
}
],
"actions": {
"ids": [
"lucy_beagle"
]
}
},
{
"rule_id": "special_needs",
"type": "pinned",
"criteria": [
{
"type": "exact",
"metadata": "work_from_home",
"values": [
"true"
]
},
{
"type": "exact",
"metadata": "fenced_in_yard",
"values": [
"true"
]
},
{
"type": "exact",
"metadata": "kids_in_house",
"values": [
"false"
]
},
{
"type": "exact",
"metadata": "cats_in_house",
"values": [
"false"
]
}
],
"actions": {
"ids": [
"toby_chihuahua"
]
}
}
]
}
解析此规则集:
- 有一个 pugs_and_pug_mixes 规则,如果查询字符串包含单词 “pug”,它将固定所有哈巴狗(pugs)和哈巴狗混种(pug mixes)
- 如果查询字符串包含 “puppy” 或 “puppies”,则 puppies 规则将返回索引中最年轻的狗 luna_dachshund
- 如果首选年龄小于或等于 2 岁,另一个 puppies2 规则将返回同一只狗(也即 luna_dachshund )
- 如果首选年龄在 2 到 10 岁之间,adult 规则将固定特定的比格犬 lucy_beagle
- 我们有一个复杂的 special_needs 规则,只有当准主人在家工作(work_from_home 为 true)、院子有围栏(fenced_in_yard 为 true)并且家里没有孩子(kids_in_house 为 false )并且猫在家里(cats_in_house 为 false),该规则才会生效。
让我们看一些示例查询 - 这些示例使用 match_none 作为有机查询,因此返回的结果仅针对规则本身。
GET query-rules-test/_search
{
"query": {
"rule": {
"organic": {
"match_none": {}
},
"ruleset_ids": [
"rescue-dog-search-ruleset"
],
"match_criteria": {
"query_string": "I like pugs and pug mixes",
"preferred_age": 5
}
}
}
}
上述查询将匹配 “pug and pug mixes”规则并返回 4 条哈巴狗结果。但是,由于首选年龄为 5 岁,我们将返回成年狗 Lucy 小猎犬作为第 5 个置顶结果。
将首选年龄更改为 1 会将哈巴狗结果下方的第 5 个结果替换为 dachshund 幼犬:
GET query-rules-test/_search
{
"query": {
"rule": {
"organic": {
"match_none": {}
},
"ruleset_ids": [
"rescue-dog-search-ruleset"
],
"match_criteria": {
"query_string": "I like pugs and pug mixes",
"preferred_age": 1
}
}
}
}
为了符合特殊需求的结果,所有标准必须符合:
{
"query": {
"rule": {
"organic": {
"match_none": {}
},
"ruleset_ids": [
"rescue-dog-search-ruleset"
],
"match_criteria": {
"work_from_home": "true",
"fenced_in_yard": "true",
"kids_in_house": "false",
"cats_in_house": "false"
}
}
}
}
如果单个条件不匹配,则不会触发此规则:
GET query-rules-test/_search
{
"query": {
"rule": {
"organic": {
"match_none": {}
},
"ruleset_ids": [
"rescue-dog-search-ruleset"
],
"match_criteria": {
"work_from_home": "true",
"fenced_in_yard": "true",
"kids_in_house": "false",
"cats_in_house": "true"
}
}
}
}
查询规则故障排除
可能很难判断是否应用了固定查询规则。有两种方法可以判断查询规则是固定了你想要的文档还是自然返回。
我们确实有 explain API,但这可能不明显:规则查询被重写为固定查询,然后被重写为恒定分数查询,因此这基本上看起来像最大可能分数:
"_explanation": {
"value": 1.7014128e+38,
"description": "max of:",
"details": [
{
"value": 1.7014128e+38,
"description": "max of:",
"details": [
{
"value": 1.7014128e+38,
"description": "ConstantScore(_id:([ff 63 68 69 68 61 75 68 75 61]))^1.7014128E38",
"details": []
},
...
]
},
...
]
}
对于 pinned rules,你还可以使用规则查询与不匹配查询相结合的方式仅返回规则,正如我们上面为了说明目的所做的那样:
GET query-rules-test/_search
{
"query": {
"rule": {
"organic": {
"match_none": {}
},
"ruleset_ids": [
"dog-breed-ruleset",
"super-special-ruleset"
],
"match_criteria": {
"breed": "pug"
}
}
}
}
或者,你可以简单地运行 organic 查询,并将该查询的结果与规则查询进行比较。
下一步是什么?
查询规则已普遍可用,但这并不意味着我们已经完成了!
我们的路线图上有很多令人兴奋的功能,包括:
- 添加对排除文档和固定文档的支持
- 无需进行 API 调用即可轻松管理查询规则的 UI
- 分析器支持
- ... 还有更多!
我们还在研究人们可能感兴趣的其他使用查询规则的方式。我们很乐意在我们的社区页面上听到你的反馈!
准备好自己尝试一下了吗?开始免费试用。
想要获得 Elastic 认证吗?了解下一次 Elasticsearch 工程师培训何时举行!
原文:Elasticsearch query rules are now generally available — Search Labs