我的索引中有两种类型(Event
和City
),我试图按日期对它们进行排序。但是,每个类型的日期字段名称不同:
对于Event
,值位于updated_at
字段中,而对于City
,日期位于update_at
字段中city_events
嵌套的其中一个嵌套对象中对象数组(注意按region_id
过滤)。
我已经尝试像这样指定排序数组中的每个字段:
"sort": [
{
"city_events.updated_at": {
"order": "desc",
"nested_path": "city_events",
"nested_filter": {
"term": {
"city_events.region_id": 1
}
}
}
},
{
"updated_at": "desc"
}
]
但不幸的是,这并没有将两种类型混合在一起。相反,它首先按其嵌套的Cities
字段对所有city_events.updated_at
进行排序,然后将所有Events
添加到其updated_at
字段排序的底部。如何将两者混合在一起?
作为替代解决方案,我尝试仅使用嵌套的city_events.updated_at
字段进行排序并指定"missing": "updated_at"
,但是尽管这两个字段的格式相同,但仍会出现"number_format_exception"
错误:
{
"error": {
"root_cause": [
{
"type": "number_format_exception",
"reason": "For input string: \"updated_at\""
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query_fetch",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "events_1461095196252",
"node": "sYQstSw_SN62ojmXgGjPlg",
"reason": {
"type": "number_format_exception",
"reason": "For input string: \"updated_at\""
}
}
]
},
"status": 400
}
更新1 :根据下面的the answer by Andrei Stefan,我尝试开发一个groovy脚本,为每个city_events
文档循环City
选择一个使用匹配的region_id
,然后返回city_event
updated_at
值进行评分,但在访问脚本中的嵌套字段时遇到问题:https://stackoverflow.com/questions/36781476/elasticsearch-access-fields-inside-array-of-nested-objects-in-a-groovy-script
答案 0 :(得分:4)
尝试基于script
的排序,您需要nested
字段才能在脚本中访问include_in_parent: true
:
"city_events": {
"type": "nested",
"include_in_parent": true,
"properties": {
"updated_at": {
"type": "date"
}
}
}
排序部分:
"sort": {
"_script": {
"type": "number",
"script": {
"inline": "if (doc['_type'].value=='Event') return doc['updated_at'].date.getMillis(); else if (doc['_type'].value=='City') return doc['city_events.updated_at'].date.getMillis()",
"lang": "groovy"
},
"order": "desc"
}
}
稍后编辑
即使我将city_events.region_id==1
条件添加到Groovy脚本中,也不会感觉到Elasticsearch,这将是纯粹的Groovy编程,而不是Elasticsearch的强大功能。
我尝试过其他方法(全部在ES 2.3.1中):
copy_to
从常规updated_at
字段到nested
内的Event
字段,以便对所有类型执行常规nested
排序。这没有用。copy_to
有效,Elasticsearch也不会与来自{"term": {"city_events.region_id": 1}
的{{1}} region_id
匹配Event
{1}}部分属于sort
类型,对于这些值,我们会使用Event
而不是实际日期(这些值来自我执行的测试)。-9223372036854776000
中的nested
字段和索引时间,将Event
放在此嵌套字段中。这与上述尝试#2的原因相同:updated_at
中必须有region_id
,以便来自Event
部分的nested
过滤器将申请两种类型。我建议,作为一种正确的处理方法,就是重新思考一下数据结构,以便排序部分(至少)遵循Elasticsearch的做法的东西。您的类型称为sort
和City
,而在Event
内您有一个(嵌套)City
列表。您是否可以在city_events
中加入Event
并复制活动'每个城市的详细信息?这不一定是标准化的RDB数据结构。相反,ES对非标准化数据更满意。
为了完整起见,我不推荐:
City
请注意,我还没有在上面的Groovy脚本中完成所有正确的检查(例如,检查文档中是否存在实际的嵌套对象)。
答案 1 :(得分:1)
应优化Elasticsearch数据以供阅读。最好的解决方案是为存储相关排序值的两种类型添加公共字段。
关于城市中的多个嵌套对象:我仍然在城市级别存储最相关(最近)的值。