我在我的laravel-app中使用了range,我正在尝试使用range-query。我有一组公司,在不同时期有不同数量的雇员,但我只对最新的时期感兴趣,在这种情况下,这意味着雇员数组的最后一项。
基本上,数组如下所示:
"company" => [
"name" => "some company",
"company_number" => "1234567",
"status" => "normal",
"employees" => [
"period_1" => [
"amount" => 10
],
"period_2" => [
"amount" => 15
],
"period_3" => [
"amount" => 24
],
etc etc...
]
]因此,在前端,您可以输入一个最小值和最大值来搜索具有一定员工数量的公司。在我的主计长中,我会这样做:
"query":{
"bool": {
"should" : [
{ "match" : { "company.status" : "normal" },
{
"range": {
"company.employees": { // I WANT THE LAST ITEM FROM THIS ARRAY
"gte": "'. $min . '",
"lt" : "'.$max .'"
}
}
}
]
}
}这基本上是可行的,但当然,没有给我员工数组的最后记录。
我怎么才能解决这个问题?请帮帮我..。
更新
好的,现在我添加了建议的代码:
"query": {
"bool": {
"should" : [
{ "match" : { "company.status" : "normal" },
{
"range": {
"company.employees": { // I WANT THE LAST ITEM FROM THIS ARRAY
"gte": "'. $min . '",
"lt" : "'.$max .'"
}
}
}
]
},
"script": {
"source": """
def period_keys = new ArrayList(ctx._source.company.employees.keySet());
Collections.sort(period_keys);
Collections.reverse(period_keys);
def latest_period = period_keys[0];
def latest_amount = ctx._source.company.employees[latest_period].amount;
ctx._source.company.current_employees = ["period": latest_period, "amount": latest_amount];
"""
}
}
}但我明白错误:Unexpected character ('{' (code 123)): was expecting comma to separate Object entries.
由于我仍然在学习,我必须说,我不知道发生了什么,来自Elasticsearch的错误消息是可怕的。
不管怎么说,有人有线索吗?提前感谢
发布于 2020-12-11 14:37:57
在运行时查找这样的内容非常困难,under-optimized.这是另一个选择。
我假设给定公司的员工数量不会经常发生变化--也就是说,当员工数量发生更改(即更新文档)时,您可以运行以下_update_by_query脚本来获取最新期间的员工信息,并将其保存在公司级别,同时保留“员工”部分:
POST companies_index/_update_by_query
{
"query": {
"match_all": {}
},
"script": {
"source": """
def period_keys = new ArrayList(ctx._source.company.employees.keySet());
Collections.sort(period_keys);
Collections.reverse(period_keys);
def latest_period = period_keys[0];
def latest_amount = ctx._source.company.employees[latest_period].amount;
ctx._source.company.current_employees = ['period': latest_period, 'amount': latest_amount];
"""
}
}单线:
POST companies_index/_update_by_query
{"query":{"match_all":{}},"script":{"source":" def period_keys = new ArrayList(ctx._source.company.employees.keySet());\n Collections.sort(period_keys);\n Collections.reverse(period_keys);\n \n def latest_period = period_keys[0];\n def latest_amount = ctx._source.company.employees[latest_period].amount;\n \n ctx._source.company.current_employees = ['period': latest_period, 'amount': latest_amount];"}}注意,当上面的查询为空时,脚本将应用于索引中的所有文档。但你当然可以把它限制在一家公司。
在调用之后,您的文档将如下所示:
{
"company" : {
"company_number" : "1234567",
"name" : "some company",
"current_employees" : { <---
"period" : "period_3",
"amount" : 24
},
"employees" : {
...
},
...
}
}上面的范围查询就成了小菜一碟:
...
"range": {
"company.current_employees.amount": { <--
"gte": "'. $min . '",
"lt" : "'.$max .'"
}
...顺便说一下,我还假设句号可以按字母顺序排序,但如果它们包含日期,脚本将需要以日期解析比较器的形式进行调整。
https://stackoverflow.com/questions/65252228
复制相似问题