Elasticsearch NEST:具有多个条件的排序术语聚合
Elasticsearch NEST: ordering terms aggregation with multiple criteria
使用 NEST,我需要能够对具有多个条件的术语聚合进行排序(需要 ElasticSearch 1.5 或更高版本)。例如:
"order": [{"avg_rank": "desc"}, {"avg_score": "desc"}]
使用我创建的原始 JSON 来验证我是否获得了预期的行为,效果很好。现在,在尝试使用 NEST 库将其转换为代码时,我不知道如何完成。
OrderDescending()
方法只有一个实现,它采用字符串作为键。我需要一个 C# "params" 类型的方法,它可以获取 OrderDescending()
and\or OrderAscending()
元素的列表。
- 有没有办法在我忽略的 NEST 中执行此操作?
- 在 NEST 中有没有办法解决这个问题,我可以在我需要的地方注入一点原始 JSON?
FWIW,我一直在使用 "fluent" 样式来创建我的查询。
编辑:
我看到,使用 "object initializer" 语法,我可以手动创建字典并添加我的条件元素。问题是,我有大量用 "fluent" 语法编写的代码。所以,
- 有没有办法使用 "object initializer" 对象并将其转换为 "fluent" 描述符?在这种情况下,TermsAggregator 到 TermsAggregationDescriptor?
编辑 2:
我本来应该提到我已经尝试 .OrderDescending("avg_rank").OrderDescending("avg_score")
了。那只是拿走了链条中的最后一个。在查看代码时,我明白了原因。每次调用 OrderDescending
都会盲目更新字典,而不是检查是否已经更新并在字典中添加新键(如果它已经存在)。
基于此,我认为这是一个错误,我已在此处提交报告:
OrderDescending and OrderAscending cannot be chained for multi-criteria ordering
编辑 3:
我感谢所有答案(其中一些已被删除),因为他们正在帮助推动这一进程并负责这些编辑。我最初也应该提到我发现:
"order": { "avg_rank": "desc", "avg_score": "desc" }
不起作用。我不确定为什么,但在这种情况下 ES 只会使用最后一个。它是一个字典列表,如我上面示例中所示。我已经验证正确地对第二个元素的聚合进行子排序。所以,底层对象不能被类型化为一个简单的字典。我还将此信息添加到我创建的错误报告中(如 EDIT 2 中所述)。
如果您使用的是流畅的语法,则可以将这些排序链接在一起。
样本:
var esClient = ninjectKernel.Get<IElasticClient>();
var query = esClient.Search<RedemptionES>(s=> s
.SortAscending(a=>a.Date)
.SortDescending(d=>d.Input.User.Name)
);
回复:
{
"sort": [
{
"@timestamp": {
"order": "asc"
}
},
{
"input.user.name": {
"order": "desc"
}
}
]
}
NEST 团队的 Martijn Laarman 反应迅速,非常友善,为我在 EDIT 2 中报告的错误提供了解决方法上面的描述。修复可以在同一个错误报告的评论中找到:Work around for NEST library multi-criteria aggregation ordering.
请注意,他为对象初始化程序和流畅的语法(我需要的)提供了解决方法。
使用 NEST,我需要能够对具有多个条件的术语聚合进行排序(需要 ElasticSearch 1.5 或更高版本)。例如:
"order": [{"avg_rank": "desc"}, {"avg_score": "desc"}]
使用我创建的原始 JSON 来验证我是否获得了预期的行为,效果很好。现在,在尝试使用 NEST 库将其转换为代码时,我不知道如何完成。
OrderDescending()
方法只有一个实现,它采用字符串作为键。我需要一个 C# "params" 类型的方法,它可以获取 OrderDescending()
and\or OrderAscending()
元素的列表。
- 有没有办法在我忽略的 NEST 中执行此操作?
- 在 NEST 中有没有办法解决这个问题,我可以在我需要的地方注入一点原始 JSON?
FWIW,我一直在使用 "fluent" 样式来创建我的查询。
编辑: 我看到,使用 "object initializer" 语法,我可以手动创建字典并添加我的条件元素。问题是,我有大量用 "fluent" 语法编写的代码。所以,
- 有没有办法使用 "object initializer" 对象并将其转换为 "fluent" 描述符?在这种情况下,TermsAggregator 到 TermsAggregationDescriptor?
编辑 2:
我本来应该提到我已经尝试 .OrderDescending("avg_rank").OrderDescending("avg_score")
了。那只是拿走了链条中的最后一个。在查看代码时,我明白了原因。每次调用 OrderDescending
都会盲目更新字典,而不是检查是否已经更新并在字典中添加新键(如果它已经存在)。
基于此,我认为这是一个错误,我已在此处提交报告: OrderDescending and OrderAscending cannot be chained for multi-criteria ordering
编辑 3: 我感谢所有答案(其中一些已被删除),因为他们正在帮助推动这一进程并负责这些编辑。我最初也应该提到我发现:
"order": { "avg_rank": "desc", "avg_score": "desc" }
不起作用。我不确定为什么,但在这种情况下 ES 只会使用最后一个。它是一个字典列表,如我上面示例中所示。我已经验证正确地对第二个元素的聚合进行子排序。所以,底层对象不能被类型化为一个简单的字典。我还将此信息添加到我创建的错误报告中(如 EDIT 2 中所述)。
如果您使用的是流畅的语法,则可以将这些排序链接在一起。
样本:
var esClient = ninjectKernel.Get<IElasticClient>();
var query = esClient.Search<RedemptionES>(s=> s
.SortAscending(a=>a.Date)
.SortDescending(d=>d.Input.User.Name)
);
回复:
{
"sort": [
{
"@timestamp": {
"order": "asc"
}
},
{
"input.user.name": {
"order": "desc"
}
}
]
}
NEST 团队的 Martijn Laarman 反应迅速,非常友善,为我在 EDIT 2 中报告的错误提供了解决方法上面的描述。修复可以在同一个错误报告的评论中找到:Work around for NEST library multi-criteria aggregation ordering.
请注意,他为对象初始化程序和流畅的语法(我需要的)提供了解决方法。