我有一个弹性查询脚本,该脚本用于使用给定的参数计算地面距离,并且必须在多个查询中使用该距离。是否有避免这种重复的方法,例如,一种用于计算全局变量的方法并在本示例中的所有脚本中使用它,我想计算distance
并在其他查询中使用它,而不是每次都不计算。
"query":{
"bool":{
"filter":[
{
"script":{
"script":{
"lang":"painless",
"params":{
"9183":4896.4,
"9238":7487.3,
"9239":7491.2,
"9402":5150.7,
"9618":2069.5,
"9656":4028.6,
"9660":3612.1,
"10049":2823.4,
"10175":3679.2,
"10204":4975.8,
"10479":5167.8,
"10486":2762.7,
"10775":3193.2,
"10801":6596.8,
"11063":2814.7,
"11470":7309.8,
"11596":2818.4,
"11780":6254.9,
"11954":3907.4,
"12001":6377.1,
"12071":3065.1,
"12258":2264.4,
"12333":6048.1,
"13088":1844.1,
"13566":2266.9,
"13576":3946.4,
"13636":3620.8,
"13696":5970.7,
"13700":1648.4,
"13810":4451.7,
"13884":2935,
"13902":2193.5,
"14271":3963.1,
"14345":2979,
"14360":2260,
"14363":2533,
"14375":4024.7,
"14685":1849,
"14703":3769.1,
"14913":3943,
"14973":6767.3,
"14976":5951.1,
"15009":3894.1,
"15270":4590.9,
"15348":4954.9,
"15360":4540.2,
"15447":5774.2,
"15534":6915.4,
"15612":5732.6,
"15789":1556.5,
"15991":3018.4,
"16051":6406.7,
"16201":2814.5,
"16247":3254.8,
"16525":2193.2,
"16547":4422.9,
"16561":3540.8,
"16613":6754.8,
"16727":3264.6,
"16731":1956.7,
"17063":4275.2,
"17181":4354.4,
"17657":2913.3,
"17757":1762.8,
"17761":3522.6,
"17777":2029,
"17895":3989,
"17965":1972.1,
"18553":3753.8,
"18586":2186.5,
"18631":1959.4,
"19006":7236,
"19022":3970.5,
"19134":3753.7,
"19150":7410.3,
"19180":4115,
"19196":5071.1,
"19276":1780.9,
"19387":3530.3,
"19393":2040.8,
"19792":4689.2,
"19903":5166.4,
"19981":6781.6,
"20132":2498.1,
"20372":6799.3,
"20387":5453.5,
"20826":3829.1,
"20838":2317.9,
"20856":2399.4,
"21134":1339.1,
"21233":3963.6,
"21266":4757,
"21269":3583.9,
"21320":3926.3,
"21490":5100.5,
"21910":4792.5,
"23104":7408.4,
"23125":4892.9,
"23167":3526.2,
"24625":6983.8,
"24985":6782.1,
"25090":3500.3,
"25129":1451.9,
"25375":4687,
"25376":4050.8,
"25458":2138.1,
"25478":4776.8,
"25652":6463,
"26224":6259.5,
"26567":2313.6,
"26594":6465.6,
"26651":2068,
"26824":3592,
"26826":6396.7,
"26890":3790.7,
"26926":5943.1,
"26932":5018.9,
"26956":3626.5,
"27012":4201.9,
"27016":4209.1,
"27017":4212.2,
"27019":4203.1,
"27020":4202.2,
"27021":4211.1,
"27026":4190.1,
"27053":1834.6,
"27055":5564.1,
"27135":6467.4,
"27232":3588.8,
"27242":5898.2,
"27257":4061.2,
"27266":6913.4,
"27318":3917.6,
"27346":2122.8,
"27365":7021,
"27368":7619.7,
"27396":5375.8,
"27460":7504.4,
"27492":3885.6,
"27557":2989.4,
"27594":2830.4,
"27683":3882.7,
"27828":3980.8,
"27865":6066.5,
"28018":6863.6,
"28057":2569.9,
"28060":2569.7,
"minDistance":0
},
"source":"def a=doc['id'].getValue();if (!params.containsKey(a.toString())) {return false;}double distance=params[a.toString()]; return distance <= doc['maxClassDeliveryDistance'].getValue() && distance >= params['minDistance']"
}
}
},
{
"script":{
"script":{
"lang":"painless",
"params":{
"9183":4896.4,
"9238":7487.3,
"9239":7491.2,
"9402":5150.7,
"9618":2069.5,
"9656":4028.6,
"9660":3612.1,
"10049":2823.4,
"10175":3679.2,
"10204":4975.8,
"10479":5167.8,
"10486":2762.7,
"10775":3193.2,
"10801":6596.8,
"11063":2814.7,
"11470":7309.8,
"11596":2818.4,
"11780":6254.9,
"11954":3907.4,
"12001":6377.1,
"12071":3065.1,
"12258":2264.4,
"12333":6048.1,
"13088":1844.1,
"13566":2266.9,
"13576":3946.4,
"13636":3620.8,
"13696":5970.7,
"13700":1648.4,
"13810":4451.7,
"13884":2935,
"13902":2193.5,
"14271":3963.1,
"14345":2979,
"14360":2260,
"14363":2533,
"14375":4024.7,
"14685":1849,
"14703":3769.1,
"14913":3943,
"14973":6767.3,
"14976":5951.1,
"15009":3894.1,
"15270":4590.9,
"15348":4954.9,
"15360":4540.2,
"15447":5774.2,
"15534":6915.4,
"15612":5732.6,
"15789":1556.5,
"15991":3018.4,
"16051":6406.7,
"16201":2814.5,
"16247":3254.8,
"16525":2193.2,
"16547":4422.9,
"16561":3540.8,
"16613":6754.8,
"16727":3264.6,
"16731":1956.7,
"17063":4275.2,
"17181":4354.4,
"17657":2913.3,
"17757":1762.8,
"17761":3522.6,
"17777":2029,
"17895":3989,
"17965":1972.1,
"18553":3753.8,
"18586":2186.5,
"18631":1959.4,
"19006":7236,
"19022":3970.5,
"19134":3753.7,
"19150":7410.3,
"19180":4115,
"19196":5071.1,
"19276":1780.9,
"19387":3530.3,
"19393":2040.8,
"19792":4689.2,
"19903":5166.4,
"19981":6781.6,
"20132":2498.1,
"20372":6799.3,
"20387":5453.5,
"20826":3829.1,
"20838":2317.9,
"20856":2399.4,
"21134":1339.1,
"21233":3963.6,
"21266":4757,
"21269":3583.9,
"21320":3926.3,
"21490":5100.5,
"21910":4792.5,
"23104":7408.4,
"23125":4892.9,
"23167":3526.2,
"24625":6983.8,
"24985":6782.1,
"25090":3500.3,
"25129":1451.9,
"25375":4687,
"25376":4050.8,
"25458":2138.1,
"25478":4776.8,
"25652":6463,
"26224":6259.5,
"26567":2313.6,
"26594":6465.6,
"26651":2068,
"26824":3592,
"26826":6396.7,
"26890":3790.7,
"26926":5943.1,
"26932":5018.9,
"26956":3626.5,
"27012":4201.9,
"27016":4209.1,
"27017":4212.2,
"27019":4203.1,
"27020":4202.2,
"27021":4211.1,
"27026":4190.1,
"27053":1834.6,
"27055":5564.1,
"27135":6467.4,
"27232":3588.8,
"27242":5898.2,
"27257":4061.2,
"27266":6913.4,
"27318":3917.6,
"27346":2122.8,
"27365":7021,
"27368":7619.7,
"27396":5375.8,
"27460":7504.4,
"27492":3885.6,
"27557":2989.4,
"27594":2830.4,
"27683":3882.7,
"27828":3980.8,
"27865":6066.5,
"28018":6863.6,
"28057":2569.9,
"28060":2569.7
},
"source":"def a=doc['id'].getValue();if (!params.containsKey(a.toString())) {return false;}double distance=params[a.toString()];return distance <= doc['maxDeliveryRadius'].getValue()"
}
}
}
]
}
}
}
映射:
{
"id":{
"type":"long"
},
"maxClassDeliveryDistance":{
"type":"long"
},
"maxDeliveryRadius":{
"type":"long"
}
}
答案 0 :(得分:2)
您应该改用stored script,以便按ID引用它:
POST _scripts/distance-script
{
"script": {
"lang": "painless",
"source":"def a=doc['id'].getValue();if (!params.containsKey(a.toString())) {return false;}double distance=params[a.toString()];return distance <= doc['maxDeliveryRadius'].getValue()"
}
}
然后您可以在查询中引用上述脚本:
{
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"lang": "painless",
"params": { ... },
"id": "distance-script"
}
}
},
{
"script": {
"script": {
"lang": "painless",
"params": { ... },
"id": "distance-script"
}
}
}
]
}
}
}
更新
我认为我们可以解决不同的问题。 bool/filter
中有两个脚本查询,这意味着AND。另外,两个脚本中的参数相同。因此,您可以将这两个脚本组合在一起,而无需使用一个脚本,就像这样:
POST _scripts/distance-script
{
"script": {
"lang": "painless",
"source":"""
def a = doc.id.value.toString();
if (!params.containsKey(a) {
return false;
}
double distance = params[a];
return distance <= doc.maxClassDeliveryDistance.value && distance >= params['minDistance'] && distance <= doc.maxDeliveryRadius.value;
"""
}
}