有这样一个需求: 展示一个用户列表, 有头像的优先展示, 有认证的优先展示, 有相册的优先展示, 同时拥有这些条件越多的则优先级更高, 第二排序条件是注册时间逆序.
通常是用条件进行过滤, 但往往是将不符合的条件数据去掉了, 而不是将其排在后面. 而对于多个条件时, 过滤更无能为力.
自定义脚本, 进行多字段评分排序, 可以很方便可以实现:
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 ] } ] } }
字段评分还能根据不同需要给予权重, 同样可以用于带搜索词的情况中, 只需要设置好对应的评分权重即可.