准备测试用例,JSON文档
{
"testdate" : ISODate("2016-12-13T16:11:03Z"),
"testname" : "石头"
}
{
"testdate" : ISODate("2016-12-13T16:11:03Z"),
"testname" : "肖晓琨"
}
{
"testdate" : ISODate("2016-12-13T16:11:03Z"),
"testname" : "张小利"
}
{
"testdate" : ISODate("2015-12-13T16:11:03Z"),
"testname" : "胡狸波"
}
{
"testdate" : ISODate("2015-12-13T16:11:03Z"),
"testname" : "石头"
}
查询插入的数据
GET test/test/_search
{
"query": {
"exists": {
"field": "testname"
}
}
}
得到的结果如下:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 5,
"max_score": 1,
"hits": [
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f58f395161f2558ac4896",
"_score": 1,
"_source": {
"testdate": "2016-12-13T16:11:03",
"testname": "石头"
}
},
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f58fc95161f2558ac4897",
"_score": 1,
"_source": {
"testdate": "2016-12-13T16:11:03",
"testname": "肖晓琨"
}
},
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f593795161f2558ac4899",
"_score": 1,
"_source": {
"testdate": "2015-12-13T16:11:03",
"testname": "胡狸波"
}
},
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f590595161f2558ac4898",
"_score": 1,
"_source": {
"testdate": "2016-12-13T16:11:03",
"testname": "张小利"
}
},
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f593e95161f2558ac489a",
"_score": 1,
"_source": {
"testdate": "2015-12-13T16:11:03",
"testname": "石头"
}
}
]
}
}
查询语句如下:
GET test/test/_search
{
"query": {
"exists" : { "field" : "testname" }
},
"sort": [
{
"testdate": {
"order": "desc"
}
},
{
"_script": {
"script": {
"inline": "'肖晓琨 '==doc['testname.keyword'].value?0:('石头'==doc['testname.keyword'].value?1:('张小利'==doc['testname.keyword'].value?2:('胡狸波'==doc['testname.keyword'].value?3:4)))"
}
"type": "number",
"order": "asc"
}
}
]
}
查询结果应当先按照日期由高到低排序,然后按照给定的序列【肖晓琨、石头、张小利、胡狸波】排序
查询的结果如下
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 5,
"max_score": null,
"hits": [
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f58fc95161f2558ac4897",
"_score": null,
"_source": {
"testdate": "2016-12-13T16:11:03",
"testname": "肖晓琨"
},
"sort": [
1481645463000,
0
]
},
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f58f395161f2558ac4896",
"_score": null,
"_source": {
"testdate": "2016-12-13T16:11:03",
"testname": "石头"
},
"sort": [
1481645463000,
1
]
},
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f590595161f2558ac4898",
"_score": null,
"_source": {
"testdate": "2016-12-13T16:11:03",
"testname": "张小利"
},
"sort": [
1481645463000,
2
]
},
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f593e95161f2558ac489a",
"_score": null,
"_source": {
"testdate": "2015-12-13T16:11:03",
"testname": "石头"
},
"sort": [
1450023063000,
1
]
},
{
"_index": "gtmetadata",
"_type": "Metadata",
"_id": "584f593795161f2558ac4899",
"_score": null,
"_source": {
"testdate": "2015-12-13T16:11:03",
"testname": "胡狸波"
},
"sort": [
1450023063000,
3
]
}
]
}
}
可以看到结果如我们所预期
通过.NET客户端构建自定义查询
使用 NEST 5.0.0
构建代码如下:
public SortDescriptor<T> BuildSort(SortRuleCollection sorts)
{
if (sorts == null || sorts.Count == 0) return null;
var sortDesc = new SortDescriptor<T>();
foreach (var s in sorts)
{
var order = s.Value.Direction == 1 ? SortOrder.Ascending : SortOrder.Descending;
if (s.Value.Promotion.Count == 0)
{
var sortField = new SortField() { Field = s.Key, Order = order };
sortDesc.Field(f => sortField);
}
else
{
var scriptField = new ScriptSort { Script = new InlineScript(GetOrderScript(s.Value, s.Key)), Order = order, Type = "number" };
sortDesc.Script(sc => scriptField);
}
}
return sortDesc;
}
private static string GetOrderScript(Sort sort, string field)
{
var value = sort.Promotion;
var sb = new StringBuilder();
for (int i = 0; i < value.Count + 1; i++)
{
string scriptText;
string itemValue;
if (i == 0)
{
itemValue = value[i].Trim();
scriptText = $"'{itemValue}'==doc['{field.KeyWord()}'].value?0";
}
else if (i == value.Count)
{
scriptText = $":{i}";
for (var j = 0; j < value.Count - 1; j++)
{
scriptText += ")";
}
}
else
{
itemValue = value[i];
scriptText = $":('{itemValue}'==doc['{field.KeyWord()}'].value?{i}";
}
sb.Append(scriptText);
}
return sb.ToString();
}
其中SortRuleCollection
/// <summary>
/// 排序规则集合
/// </summary>
[Serializable]
[DataContract]
public class SortRuleCollection : Dictionary<string, Sort>
{
}
/// <summary>
/// 单个排序规则
/// </summary>
[DataContract]
public class Sort
{
/// <summary>
/// 无参构造
/// </summary>
public Sort() { }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="direction"></param>
public Sort(int direction)
{
this.Direction = direction;
this.Promotion = new List<string>();
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="direction"></param>
/// <param name="promotion"></param>
public Sort(int direction, List<string> promotion)
{
this.Direction = direction;
this.Promotion = promotion;
}
/// <summary>
/// 排序方向
/// </summary>
[DataMember(Name = "direction")]
public int Direction { get; set; }
/// <summary>
/// 排序自定义值
/// </summary>
[DataMember(Name = "promotion")]
public List<string> Promotion { get; set; }
}
这个属于ES5.0的写法
ES1.x的写法请查看另一篇博客 http://blog.csdn.net/shiyaru1314/article/details/50837544