有这样一个需求: 展示一个用户列表, 有头像的优先展示, 有认证的优先展示, 有相册的优先展示, 同时拥有这些条件越多的则优先级更高, 第二排序条件是注册时间逆序.
通常是用条件进行过滤, 但往往是将不符合的条件数据去掉了, 而不是将其排在后面. 而对于多个条件时, 过滤更无能为力.
自定义脚本, 进行多字段评分排序, 可以很方便可以实现:
1. 写入配置文件, 开启script支持, 并重启Elasticsearch
script.groovy.sandbox.enabled: true
script.inline: on
script.indexed: on
script.search: on
script.engine.groovy.inline.aggs: on
script.engine.groovy.inline.search: on
2. 创建索引
PUT /users
{
"mappings": {
"list" : {
"properties": {
"Name": {
"type": "string",
"analyzer": "standard",
"index": "analyzed"
},
"HasAvatar": {
"type": "long"
},
"HasAlbum": {
"type": "long"
},
"HasAuth": {
"type": "long"
},
"RegTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
}
3. 添加测试数据
POST /users/list/_bulk
{"index": {"_id": 1}}
{"Name": "Allen", "HasAvatar": 1, "HasAlbum": 1, "HasAuth": 1, "RegTime": "2015-12-01 00:00:00"}
{"index": {"_id": 2}}
{"Name": "Burnell", "HasAvatar": 0, "HasAlbum": 0, "HasAuth": 0, "RegTime": "2015-11-02 00:00:00"}
{"index": {"_id": 3}}
{"Name": "Chasel", "HasAvatar": 0, "HasAlbum": 0, "HasAuth": 0, "RegTime": "2015-11-22 00:00:00"}
{"index": {"_id": 4}}
{"Name": "Eden", "HasAvatar": 1, "HasAlbum": 0, "HasAuth": 1, "RegTime": "2015-12-02 00:00:00"}
{"index": {"_id": 5}}
{"Name": "Ford", "HasAvatar": 1, "HasAlbum": 1, "HasAuth": 0, "RegTime": "2015-12-03 00:00:00"}
{"index": {"_id": 6}}
{"Name": "Gordon", "HasAvatar": 1, "HasAlbum": 0, "HasAuth": 0, "RegTime": "2015-12-04 00:00:00"}
4. 按条件搜索
GET /users/list/_search
{
"sort": [{
"_script": {
"script": "doc['HasAvatar'].value + doc['HasAlbum'].value + doc['HasAuth'].value",
"type": "number",
"order": "desc"
},
"RegTime":{"order": "desc"}
}]
}
看看结果是不是符合预期:
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 6,
"max_score": null,
"hits": [
{
"_index": "users",
"_type": "list",
"_id": "1",
"_score": null,
"_source": {
"Name": "Allen",
"HasAvatar": 1,
"HasAlbum": 1,
"HasAuth": 1,
"RegTime": "2015-12-01 00:00:00"
},
"sort": [
3,
1448928000000
]
},
{
"_index": "users",
"_type": "list",
"_id": "5",
"_score": null,
"_source": {
"Name": "Ford",
"HasAvatar": 1,
"HasAlbum": 1,
"HasAuth": 0,
"RegTime": "2015-12-03 00:00:00"
},
"sort": [
2,
1449100800000
]
},
{
"_index": "users",
"_type": "list",
"_id": "4",
"_score": null,
"_source": {
"Name": "Eden",
"HasAvatar": 1,
"HasAlbum": 0,
"HasAuth": 1,
"RegTime": "2015-12-02 00:00:00"
},
"sort": [
2,
1449014400000
]
},
{
"_index": "users",
"_type": "list",
"_id": "6",
"_score": null,
"_source": {
"Name": "Gordon",
"HasAvatar": 1,
"HasAlbum": 0,
"HasAuth": 0,
"RegTime": "2015-12-04 00:00:00"
},
"sort": [
1,
1449187200000
]
},
{
"_index": "users",
"_type": "list",
"_id": "3",
"_score": null,
"_source": {
"Name": "Chasel",
"HasAvatar": 0,
"HasAlbum": 0,
"HasAuth": 0,
"RegTime": "2015-11-22 00:00:00"
},
"sort": [
0,
1448150400000
]
},
{
"_index": "users",
"_type": "list",
"_id": "2",
"_score": null,
"_source": {
"Name": "Burnell",
"HasAvatar": 0,
"HasAlbum": 0,
"HasAuth": 0,
"RegTime": "2015-11-02 00:00:00"
},
"sort": [
0,
1446422400000
]
}
]
}
}
字段评分还能根据不同需要给予权重, 同样可以用于带搜索词的情况中, 只需要设置好对应的评分权重即可.