我的文档映射如下所示:
"_source": {
"id": 60,
"price": 60,
"locations": [
{
"id": 1
"price": 70
},
{
"id": 5,
"price": 80
}
]
}
因此,价格字段既可以位于根数组中,也可以位于嵌套位置数组中。我希望能够按两个值过滤它们 - 如果在查询参数中设置
locationId
,则按位置中的价格过滤,否则 - 按根价格过滤。
我写了无痛脚本:
if(params['locationId'] != null){
for (def location : doc['locations']) {
if (location.id == params['locationId']) {
if ((params['lte'] != null || location.price <= params['lte']) && (params['gte'] != null || location.price >= params['gte'])) {
return true;
} else {
return false;
}
}
}
}
return (params['lte'] != null || params._source.price <= params['lte']) && (params['gte'] != null || params._source.price >= params['gte']);
现在我正在尝试使用它:
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"source": "my_script",
"params": {
"locationId": "2"
}
}
}
}
]
}
}
但是我的脚本第二行出现错误。
No field found for [locations] in mapping with types []
我该如何解决这个问题?我还尝试通过 locations
访问 params._source.locations
,就像我在排序脚本中所做的类似操作一样,但是 params
无法从 filters
查询访问
尝试使用运行时字段
您的地图
PUT /outer_inner_prices
{
"mappings": {
"properties": {
"id": {
"type": "integer"
},
"price": {
"type": "integer"
},
"locations": {
"type": "nested",
"properties": {
"id": {
"type": "integer"
},
"price": {
"type": "integer"
}
}
}
}
}
}
还有你的文件
PUT /outer_inner_prices/_bulk
{"create":{"_id":1}}
{"id":60,"price":60,"locations":[{"id":1,"price":70},{"id":5,"price":80}]}
运行时字段和您的
bool
查询
GET /outer_inner_prices/_search?filter_path=hits.hits
{
"runtime_mappings": {
"filtered_price": {
"type": "boolean",
"script": {
"source": """
boolean isValid(long value, Integer lte, Integer gte) {
if (lte == null) {
return false;
}
if (gte == null) {
return false;
}
return (value <= lte.longValue()) && (value >= gte.longValue());
}
if (params['locationId'] == null) {
long value = doc['price'].value;
emit(isValid(value, params['lte'], params['gte']));
return;
} else {
List locations = params['_source']['locations'];
for (def location : locations) {
if (location.id == params['locationId']) {
long value = location.price;
emit(isValid(value, params['lte'], params['gte']));
return;
}
}
emit(false);
}
""",
"params": {
"locationId": 5,
"gte": 1,
"lte": 80
}
}
}
},
"query": {
"bool": {
"filter": [
{
"term": {
"filtered_price": "true"
}
}
]
}
}
}
我已将您的代码移至运行时字段并重构了它
回应
{
"hits" : {
"hits" : [
{
"_index" : "outer_inner_prices",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.0,
"_source" : {
"id" : 60,
"price" : 60,
"locations" : [
{
"id" : 1,
"price" : 70
},
{
"id" : 5,
"price" : 80
}
]
}
}
]
}