[英]Elasticsearch: Unable to order results using script_score
I have a field called price in my elasticsearch index whose values I need to convert before sorting - 我的Elasticsearch索引中有一个名为price的字段,在排序之前需要转换其值-
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "products",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"prod_id" : 1,
"currency" : "USD",
"price" : 1
}
},
{
"_index" : "products",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"prod_id" : 2,
"currency" : "INR",
"price" : 60
}
},
{
"_index" : "products",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"prod_id" : 3,
"currency" : "EUR",
"price" : 2
}
},
{
"_index" : "products",
"_type" : "_doc",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"prod_id" : 5,
"currency" : "MYR",
"price" : 1
}
}
]
}
}
As the currency field
for each product is different, 由于每种产品的
currency field
不同,
I plan to convert each product's price into USD , 我计划将每种产品的价格转换为USD ,
Using the script_score
function, as recommended here - 按照此处的建议使用
script_score
函数-
Elastic Search sort preprocessing 弹性搜索排序预处理
I tried the following query - 我尝试了以下查询-
GET products/_search
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"functions": [{
"script_score": {
"script": {
"params": {
"USD": 1,
"SGD": 0.72,
"MYR": 0.24,
"INR": 0.014,
"EUR": 1.12
},
"source": "doc['price'].value * params.doc['currency']"
}
}
}]
}
},
"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
I'm getting an error - 我遇到错误-
{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"doc['price'].value * params.doc['currency']",
" ^---- HERE"
],
"script": "doc['price'].value * params.doc['currency']",
"lang": "painless"
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "products",
"node": "5-fQ27BhSUKycVJ2SwyH4A",
"reason": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"doc['price'].value * params.doc['currency']",
" ^---- HERE"
],
"script": "doc['price'].value * params.doc['currency']",
"lang": "painless",
"caused_by": {
"type": "class_cast_exception",
"reason": "Cannot apply [*] operation to types [java.lang.Long] and [org.elasticsearch.index.fielddata.ScriptDocValues.Strings]."
}
}
}
]
},
"status": 400
}
Expected product sequence - 预期产品顺序-
1. prod_id 3 , _score 2.24 = 2(price) * 1.12 (USD multiplier)
1. prod_id 3 ,_score 2.24 =
2(price) * 1.12 (USD multiplier)
2. prod_id 1 , _score 1 = 1(price) * 1 (USD multiplier) = 1
2. prod_id 1 ,_score 1 =
1(price) * 1 (USD multiplier) = 1
3. prod_id 2 , _score 0.84 = 60(price) * 0.014 (USD multiplier)
3. prod_id 2 ,_score 0.84 =
60(price) * 0.014 (USD multiplier)
4. prod_id 5 , _score 0.24 = 1(price) * 0.24 (USD multiplier)
4. prod_id 5 ,_score 0.24 =
1(price) * 0.24 (USD multiplier)
Index Mapping - 索引映射-
{
"mapping": {
"properties": {
"currency": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"fielddata": true
},
"price": {
"type": "long"
},
"prod_id": {
"type": "long"
}
}
}
}
Can someone please help for this use case query? 有人可以为这个用例查询提供帮助吗?
test 1 - 测试1-
test 2 -
测试2-
null_pointer_exception -
空指针异常 -
Since the currency
has type text
, it is indexed with Standard Analyzer which converts it to lower case. 由于
currency
类型为text
,因此使用Standard Analyzer对其进行了索引,从而将其转换为小写形式。
That means, when currency is MYR
, it is indexed as myr
, so the script should be something like: 这意味着,当currency为
MYR
,其索引为myr
,因此脚本应类似于:
doc.currency.value == 'myr' ? params.MYR : 1
If currency
is "type":"keyword"
, then you can use: 如果
currency
是"type":"keyword"
,则可以使用:
doc.currency.value === 'MYR' ? params.MYR : 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.