首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >弹性搜索排序预处理

弹性搜索排序预处理
EN

Stack Overflow用户
提问于 2015-08-17 19:59:14
回答 1查看 777关注 0票数 1

我在ES中有一个索引,除了其他字段外,还有revenue_amount和revenue_currency字段。收入以不同的货币储存。在运行时,所有货币都转换为美元并呈现。

现在,我想支持在revenue_amount字段上进行排序。问题是ES在转换成美元之前对收入进行排序,因此在最高收入处返回的收入可能不是转换成美元后的最高收入。

我想知道,在排序之前,ES是否会调用一个用户定义的函数来更改字段值,然后应用排序呢?就像这样:

revenue_converted =convertToUSD(收入)

因此,排序将应用于revenue_converted,而不是收入。

我知道我可以在指数时间转换货币,但这将需要每次更新汇率时刷新索引,所以如果可能的话,我想避免它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-18 03:58:59

实现这一目标有两种方法:一种是使用基于脚本的排序作为关键:

代码语言:javascript
复制
{
    "query" : {
        ....                                    <--- your query goes here
    },
    "sort" : {
        "_script" : {
            "script" : "doc.revenue_amount.value * usd_conversion_rate",
            "type" : "number",
            "params" : {
                "usd_conversion_rate" : 0.4273  <--- the conversion rate to USD
            },
            "order" : "desc"
        }
    }
}

usd_conversion_rate系数是对美元的换算率。例如,如果1美元相当于另一种货币的2.34单位,usd_conversion_rate系数将是1 / 2.34 (或0.4273)。当与revenue_amount相乘时,它将给出以美元参考货币表示的金额。

但是,基于脚本的排序并不是很好的表现,建议使用一个function_score,这样就可以用分数来排序结果。这将我们引向第二种方式来实现你所需要的,它是这样的。一种方法是使用script_score函数,但这需要重新编写脚本。

代码语言:javascript
复制
{
  "query": {
    "function_score": {
      "query": {},
      "functions": [
        {
          "script_score": {
            "script": "doc.revenue_amount.value * usd_conversion_rate",
            "boost_mode": "replace",
            "params": {
              "usd_conversion_rate": 0.4273
            }
          }
        }
      ]
    }
  }
}

由于上面的脚本非常简单(即用某个因素乘以一个字段),最简单的方法是使用field_value_factor,它如下所示:

代码语言:javascript
复制
{
  "query": {
    "function_score": {
      "query": {
        ...                              <--- your query goes here
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "revenue_amount",
            "boost_mode": "replace",
            "factor": 0.4273             <--- insert the conversion rate here
          }
        }
      ]
    }
  }
}

更新

根据您最近的评论,对您来说,最终正确的选择似乎是使用script_score。这里的想法是将查找表中可用的所有货币汇率作为script_score脚本的参数输入,然后根据revenue_currency字段的值使用合适的汇率。

代码语言:javascript
复制
{
  "query": {
    "function_score": {
      "query": {},
      "functions": [
        {
          "script_score": {
            "script": "doc.revenue_amount.value * (doc.revenue_currency.value == 'EUR' ? EUR : (doc.revenue_currency.value == 'AUD' ? AUD : 1))",
            "boost_mode": "replace",
            "params": {
              "EUR": 0.4945,
              "AUD": 0.5623
            }
          }
        }
      ]
    }
  }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32058673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档