如何在弹性无痛脚本中实现单例

时间:2018-08-21 06:25:49

标签: elasticsearch elasticsearch-painless

我在弹性搜索方面很轻松,例如:

POST _scripts/painless/calculate-price
{
  "script": "Map currencyMap = ['USD': 6.8, 'RUB': 0.122]; return doc['price'] * currencyMap[doc['currency']];"
}

我使用此脚本对数据进行排序,currencyMap的大小对时间成本有巨大影响。

那么有没有一种方法可以轻松实现单例,那么我只能一次初始化currencyMap并使用多次?

任何帮助将不胜感激。

PS:

以下是我的测试脚本,测试文档数为5738306。

compute-score花费了2000ms(avg),600ms(avg)。

POST _scripts/calculate-score
{
  "script": {
    "lang": "painless",
    "source": "Map currencyMap = ['A': 6.8, 'B': 0.122, 'BC': 0.122, 'C': 0.122, 'D': 0.122, 'E': 0.122, 'F': 0.122, 'G': 0.122, 'H': 0.122, 'I': 0.122, 'J': 0.122, 'K': 0.122, 'L': 0.122, 'M': 0.122, 'N': 0.122, 'O': 0.122, 'P': 0.122, 'Q': 0.122, 'R': 0.122, 'S': 0.122, 'T': 0.122, 'U': 0.122, 'V': 0.122, 'W': 0.122, 'X': 0.122, 'BY': 0.122, 'BZ': 0.122, 'AB': 0.122, 'BB': 0.122, 'CB': 0.122]; def price = doc['price'].getValue(); def currency = doc['currency']; if(doc['currency'] == null) {doc['currency'] = 'A';} def c =  currencyMap[currency]; if(c == null) {c = 0.11;}return price * c;"
  }
}

POST _scripts/calculate-score2
{
  "script": {
    "lang": "painless",
    "source": "Map currencyMap = ['A': 6.8]; def price = doc['price'].getValue(); def currency = doc['currency']; if(doc['currency'] == null) {doc['currency'] = 'A';} def c =  currencyMap[currency]; if(c == null) {c = 0.11;}return price * c;"
  }
}

GET /test/_search
{
  "_source": ["price", "currency"], 
  "sort" : {
        "_script" : {
            "type" : "number",
            "script" : {
                "id": "calculate-score"
            },
            "order" : "desc"
        }
    }
}

GET /test/_search
{
  "_source": ["price", "currency"], 
  "sort" : {
        "_script" : {
            "type" : "number",
            "script" : {
                "id": "calculate-score2"
            },
            "order" : "desc"
        }
    }
}

0 个答案:

没有答案