elasticsearch的父子_关于排序:ElasticSearch多级父子聚合

我有3个级别的父级/子级结构。比方说:

Company -> Employee -> Availability

由于可用性(以及员工)在这里经常更新,因此我选择对嵌套使用父/子结构。搜索功能也可以正常工作(所有文档都位于正确的分片中)。

现在,我想对这些结果进行排序。按公司(第一级)的元数据对它们进行排序很容易。但是我还需要按3级(可用性)进行排序。

我想要按以下方式排序的公司列表:

给定ASC到位置的距离

评分DESC

尽快供货ASC

例如:

公司A在5英里之外,具有4级,并且最快有20个小时可以找到一名员工

公司B也位于5英里之外,评级也为4,但他们的一名员工最快会在5个小时内上班。

因此排序结果必须为B,A。

我想对每个数据附加特殊的权重,因此我开始编写聚合,以后可以在custom_score脚本中使用。

创建索引,导入数据和搜索的完整依据

现在,我设法编写了一个查询,该查询实际上返回了结果,但是可用性聚合存储桶为空。

但是,我也将结果重新整理得井井有条,我想将它们弄平。

目前我回来了:

Company IDS -> Employee IDS -> first availability

我想要像这样的聚合:

Company IDS -> first availability

这样,我就可以执行custom_score脚本来计算分数并对其进行正确排序。

更简化的问题:

一个如何对多级(大)孩子进行排序/汇总,并可能将结果弄平。

您可以将映射和一些示例文档(带有后代)添加到要点吗?很难看到如何发明可以对系统进行适当测试的伪造文档。

嘿斯隆-Ive添加了映射和示例结果。香港专业教育学院剥离它,以便于理解。全栈中有更多数据:)谢谢!

我在这里有同样的问题。尽管性能可能较低,但我只是请求所有具有默认类型DocCount的结果。然后,我自己进行了递归展平,排序和限制,这并不是理想的选择。

我已经执行了要点,但是搜索时出现错误500 Query Failed [Failed to execute main query]]; nested: NullPointerException;。您能否在本地环境中执行要点并确保一切正常?谢谢!

为什么不为您的结果创建方程式。您的数据不模糊!您汇总每个查询? 。聚合是输入操作,而不是查询或输出。一个问题"如何检查此结果是否为True(正确)?"

使用哪个版本的ElasticSearch?我得到一个" nullPointerException"(我猜是因为我的版本)。我使用的是1.4.5版本。

您不需要进行聚合:

这些是排序标准:

距离ASC(公司位置)

评分DESC(company.rating_value)

不久的将来的可用性ASC(company.employee.availability.start)

如果忽略#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之所以棘手,是因为您需要深入了解每个公司与请求时间最接近的可用性(公司>员工>可用性),并将该持续时间用作第三排序标准。

我们将在孙级使用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)"

}

}

]

}

因此,现在每个孙子代的_score(可用性)将为1 / number-of-hours-until-available(以便我们可以使用直到每个员工可用的最大倒数时间,以及每个公司可以使用的最大员工倒数)。

综上所述,我们继续查询公司,但使用公司>雇员>可用性生成_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" }

}

}

使用线性衰减函数而不是从时间到可用生成_score的脚本,可能会获得更好的性能。

Elasticsearch默认情况下禁用动态脚本。 更好的方法是使用索引脚本。 看到这里:elastic.co/blog/

皮特·米纳斯(Pete Minus):您能使它正常工作吗? 我知道这是一个比较老的问题,但是有很多人对您的解决方案感兴趣。

彼得·迪克森-摩西(Peter Dixon-Moses):最终,我放弃了并写下了两个查询-首先按公司/员工进行搜索,然后通过"可用性"搜索排名前100位的公司,然后合并。 为什么? 仅在ES中构建它要花费太多时间/精力。 搜索所花费的时间是可以接受的。

您应该查看R-Tree数据结构https://en.wikipedia.org/wiki/R-tree。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值