无论才能、知识多么卓著,如果缺乏热情,则无异纸上画饼充饥,无补于事。

es自定义排序错乱问题

Elasticsearch | 作者 fantaigan | 发布于2020年03月19日 | 阅读数:396

es6,请教大家,我想让id=1,2,3,4的四条数据排在最前面,剩下的数据再根据时间降序要怎么做呢?我用了function score设置了weight,然后根据评分降序再用创建时间降序,可以让符合id条件的排前面,但后面的数据时间顺序是错乱的。不知道问题出在哪里,或者说我这样做是行不通的?
已邀请:

God_lockin

赞同来自: fantaigan laoyang360

考虑用script sort吗?
 
先给答案,可以用这个script。
POST test/_search
{
"sort": [
{
"_script": {
"script": {
"source": """String id = doc['_id'].getValue(); if ("1".equals(id) || "2".equals(id)) { return Integer.parseInt(id) * System.nanoTime(); } else { return doc['time'].getValue().toInstant().toEpochMilli(); }"""
},
"type": "number",
"order": "desc"
}
}
]
}

准备数据
Mapping
PUT test
{
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "0"
}
},
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"time": {
"type": "date",
"format": [
"yyyy-MM-dd HH:mm:ss"
]
}
}
}
}

数据:
POST test/_doc/1
{
"name": "1",
"time": "2020-02-02 09:00:00"
}

POST test/_doc/2
{
"name": "2",
"time": "2020-02-02 08:00:00"
}

POST test/_doc/3
{
"name": "3",
"time": "2020-02-02 05:00:00"
}

POST test/_doc/4
{
"name": "4",
"time": "2020-02-02 06:00:00"
}

简化一下题目,id=1,2的按顺序返回,也可以逆序,看你自己的需求,其他的按时间倒序。
思路:把id=1,2的单独拿出来给个大参数(比如当前时间),然后其他的按时间倒排。
分别对应
Integer.parseInt(id) * System.nanoTime();

doc['time'].getValue().toInstant().toEpochMilli();
 
最终结果
{
"took" : 11,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "test",
"_type" : "_doc",
"_id" : "2",
"_score" : null,
"_source" : {
"name" : "2",
"time" : "2020-02-02 08:00:00"
},
"sort" : [
3.985284816144E12
]
},
{
"_index" : "test",
"_type" : "_doc",
"_id" : "1",
"_score" : null,
"_source" : {
"name" : "1",
"time" : "2020-02-02 09:00:00"
},
"sort" : [
1.992642329371E12
]
},
{
"_index" : "test",
"_type" : "_doc",
"_id" : "4",
"_score" : null,
"_source" : {
"name" : "4",
"time" : "2020-02-02 06:00:00"
},
"sort" : [
1.5806232E12
]
},
{
"_index" : "test",
"_type" : "_doc",
"_id" : "3",
"_score" : null,
"_source" : {
"name" : "3",
"time" : "2020-02-02 05:00:00"
},
"sort" : [
1.5806196E12
]
}
]
}
}

 

tacsklet - 公司有用到es

赞同来自:

我觉得这个是一个设计问题。感觉你想实现的是多字段排序,首先根据4个id排序,然后根据时间排序。因为id是每条数据都有的,只根据部分去排不好排。可以对这4条数据增加一个字段比如sortId=1,2,3,4,然后排序的时候通过order by sortId, timestamp; 这样的话应该能满足你的需求。

caizhongao

赞同来自:

把你的语句贴出来

xzorz

赞同来自:

语句贴一下

要回复问题请先登录注册