如何解决如何在嵌套的 script_score 上的过滤器之间添加?
我正在使用给定的货币汇率动态过滤价格,并使用脚本生成的分数对其进行排序。但是有一件事我不知道该怎么做,那就是范围过滤器。
例如,我只想让 product_platforms 只匹配 10 到 100 之间的分数。
索引请求。
PUT /test_products
{
"settings": {
"number_of_shards": 3,"number_of_replicas": 0,"analysis": {
"filter": {
"autocomplete_filter": {
"type": "edge_ngram","min_gram": "2","max_gram": "15"
}
},"analyzer": {
"autocomplete": {
"type": "custom","tokenizer": "standard","filter": [
"lowercase","autocomplete_filter"
]
}
}
}
},"mappings": {
"properties": {
"id": {
"type": "keyword","doc_values": true
},"name": {
"type": "text","fields": {
"keyword": {
"type": "keyword"
},"raw": {
"type": "keyword"
}
},"analyzer": "autocomplete","search_analyzer": "standard"
},"product_platforms": {
"type": "nested","properties": {
"id": {
"type": "long"
},"platform_id": {
"type": "long"
},"price": {
"type": "float"
},"currency_id": {
"type": "long"
},"currency_code": {
"enabled": false
},"sku": {
"type": "keyword"
},"quantity": {
"type": "long"
}
}
}
}
}
}
插入测试文档:
POST /test_products/_bulk?pretty&refresh
{"index":{"_id": 1}}
{"id": 1,"name": "1. Product","product_platforms": [{"id": 11,"platform_id": 3,"price": 100,"currency_id": 1,"currency_code": "TRY","sku": "URN_1_1","quantity": 1},{"id": 12,"price": 75,"currency_id": 2,"currency_code": "USD","sku": "URN_1_2",{"id": 13,"platform_id": 2,"price": 15,"sku": "URN_1_3","quantity": 1}]}
{"index":{"_id": 2}}
{"id": 2,"name": "2. Product","product_platforms": [{"id": 21,"price": 50,"sku": "URN_2_1",{"id": 22,"price": 25,"sku": "URN_2_2",{"id": 23,"sku": "URN_2_3",{"id": 24,"price": 20,"sku": "URN_2_4","quantity": 1}]}
GET /test_products/_search
{
"query": {
"nested": {
"path": "product_platforms","score_mode": "max","query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"term": {
"product_platforms.platform_id": {
"value": "3"
}
}
}
]
}
},"boost_mode": "replace","script_score": {
"script": {
"source": """
doc['product_platforms.price'].value * (doc['product_platforms.currency_id'].value == 2 ? params.rate_usd : (doc['product_platforms.currency_id'].value == 3 ? params.rate_eur : params.rate_try)) ""","params": {
"rate_try": 1,"rate_usd": 7,"rate_eur": 8
}
}
}
}
},"inner_hits": {
"name": "product_platforms","_source": true,"size": 5,"sort": {
"_script": {
"type": "number","script": {
"lang": "painless","source": """ doc['product_platforms.price'].value * (doc['product_platforms.currency_id'].value == 2 ? params.rate_usd : (doc['product_platforms.currency_id'].value == 3 ? params.rate_eur : params.rate_try)) ""","rate_eur": 8
}
},"order": "desc"
}
}
}
}
},"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
顺便说一句,我使用的是 7.10 版。
解决方法
您可以再次重复那个分数计算器,这次是用它自己的布尔值 script
query。
现在,由于您的货币转换脚本重复了太多次,您可以store it 并在每次需要时通过其 ID 引用它。您当然会保持利率参数化,但整个过程将更具可读性和可维护性。
那么,让我们先保存脚本:
POST _scripts/product-platforms-converter
{
"script": {
"source": """
def price = doc['product_platforms.price'].value;
def currency_id = doc['product_platforms.currency_id'].value;
def converted_price = price * (currency_id == 2
? params.rate_usd : (currency_id == 3
? params.rate_eur : params.rate_try));
if (params.final_range != null) {
def is_in_range = converted_price >= params.final_range.gte
&& converted_price <= params.final_range.lte;
return is_in_range;
}
return converted_price;
""","lang": "painless"
}
}
请注意,如果 final_range
中提供了 params
,脚本将返回 boolean
;如果没有,它只会返回 converted_price
。
之后,原始查询可以改写为:
GET /test_products/_search
{
"query": {
"nested": {
"path": "product_platforms","score_mode": "max","query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"term": {
"product_platforms.platform_id": {
"value": "3"
}
}
},{
"script": {
"script": {
"id": "product-platforms-converter","params": {
"rate_try": 1,"rate_usd": 7,"rate_eur": 8,"final_range": { <--- the desired "range" query
"gte": 10,"lte": 100
}
}
}
}
}
]
}
},"boost_mode": "replace","script_score": {
"script": {
"id": "product-platforms-converter","params": {
"rate_try": 1,"rate_eur": 8
}
}
}
}
},"inner_hits": {
"name": "product_platforms","_source": true,"size": 5,"sort": {
"_script": {
"type": "number","script": {
"id": "product-platforms-converter","rate_eur": 8
}
},"order": "desc"
}
}
}
}
},"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。