ElasticSearch5.0——自定义排序规则

准备测试用例,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" : "石头"
}


插入到ES服务器

查询插入的数据

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": "石头"
        }
      }
    ]
  }
}


接下来使用sort的script脚本,来执行自定义的查询


查询语句如下:

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  





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值