我有一个3层的父/子结构。比方说:
公司-> Employee ->可用性
由于可用性(以及员工)在这里经常更新,因此我选择使用父/子结构而不是嵌套。搜索功能运行良好(所有文档都在正确的分片中)。
现在我想对这些结果进行排序。通过来自公司(第一级)的元数据对它们进行排序很容易。但我也需要按第三级(可用性)排序。
我想要按以下顺序排序的公司列表:
例如:
公司A在5英里外,评级为4,最快有一名员工在20小时内到达;公司B也在5英里外,评级为4,但最快有一名员工在5小时内到达。
因此,排序结果需要是B,A。
我想为每个数据添加特殊的权重,所以我开始编写聚合,稍后我可以在custom_score脚本中使用这些聚合。
现在,我已经设法编写了一个实际返回结果的查询,但可用性聚合存储桶为空。然而,我也得到了太结构化的结果,我想要扁平化它们。
现在我回来了:
公司IDS ->员工IDS -> first可用性
我希望有如下聚合:
公司IDS -> first availability
这样,我就能够执行custom_score
脚本来计算分数并对它们进行适当的排序。
更简单的问题:
如何按多级(大)子级进行排序/聚合,并可能使结果扁平化。
发布于 2015-08-12 01:37:19
你不需要聚合来做到这一点:
以下是排序条件:
ASC (company.location)
的
如果忽略#3,则可以运行一个相对简单的公司查询,如下所示:
GET /companies/company/_search
{
"query": { "match_all" : {} },
"sort": {
"_script": {
"params": {
"lat": 51.5186,
"lon": -0.1347
},
"lang": "groovy",
"type": "number",
"order": "asc",
"script": "doc['location'].distanceInMiles(lat,lon)"
},
"rating_value": { "order": "desc" }
}
}
#3很棘手,因为您需要深入了解最接近请求时间的每个公司的可用性( company > employee > availability ),并使用该持续时间作为第三个排序标准。
我们将在孙子级别使用function_score
查询,以获取请求时间与命中_score
中的每个可用性之间的时间差。(然后我们将使用_score
作为第三个排序标准)。
为了到达子代,我们需要在has_child
查询中使用has_child
查询。
对于每家公司,我们都想要最快有空的员工(当然还有他们最近的空闲时间)。对于这种情况,Elasticsearch 2.0将为我们提供一个"score_mode": "min"
,但现在,由于我们仅限于"score_mode": "max"
,我们将使孙子_score
成为时差的倒数。
"function_score": {
"filter": {
"range": {
"start": {
"gt": "2014-12-22T10:34:18+01:00"
}
}
},
"functions": [
{
"script_score": {
"lang": "groovy",
"params": {
"requested": "2014-12-22T10:34:18+01:00",
"millisPerHour": 3600000
},
"script": "1 / ((doc['availability.start'].value - new DateTime(requested).getMillis()) / millisPerHour)"
}
}
]
}
因此,现在每个孙子(Availability)的_score
将是1 / number-of-hours-until-available
(这样我们就可以使用最大倒数时间,直到每个员工都可用,最大倒数(ly?)每个公司的可用员工)。
总而言之,我们继续查询公司,但使用company > employee > availabilty生成_score
,用作#3排序标准:
GET /companies/company/_search
{
"query": {
"has_child" : {
"type" : "employee",
"score_mode" : "max",
"query": {
"has_child" : {
"type" : "availability",
"score_mode" : "max",
"query": {
"function_score": {
"filter": {
"range": {
"start": {
"gt": "2014-12-22T10:34:18+01:00"
}
}
},
"functions": [
{
"script_score": {
"lang": "groovy",
"params": {
"requested": "2014-12-22T10:34:18+01:00",
"millisPerHour": 3600000
},
"script": "1/((doc['availability.start'].value - new DateTime(requested).getMillis()) / millisPerHour)"
}
}
]
}
}
}
}
}
},
"sort": {
"_script": {
"params": {
"lat": 51.5186,
"lon": -0.1347
},
"lang": "groovy",
"type": "number",
"order": "asc",
"script": "doc['location'].distanceInMiles(lat,lon)"
},
"rating_value": { "order": "desc" },
"_score": { "order": "asc" }
}
}
发布于 2015-08-09 17:11:52
您应该查看R树数据结构https://en.wikipedia.org/wiki/R-tree。
https://stackoverflow.com/questions/27510798
复制相似问题