从这篇文章开始,我们要进入DSL的学习。
使用url搜索仅仅是个开始,ES还提供带有查询DSL的请求体用于更高级的搜索。在这些类型的搜索中有大量可选项,可以混合和匹配不同的选项以获得所需的结果。
DSL还能根据查询子句的过滤和查询上下文,使用筛选器的子句以布尔形式测试Document是否匹配筛选器。过滤器通常也比查询快,但是查询也可以根据Document与查询的匹配程度来计算score。
From/Size
分页可以说是最常用的一个功能了,在ES里通过使用From/Size实现结果分页。from参数定义了要获取的第一个结果的偏移量,size参数允许配置要返回的最多命中数量。
虽然可以将from和size设置为请求参数,但它们也可以在搜索体中设置。从默认值到0,大小默认值10:
GET http://localhost:9200/orders/_search { "from" : 0, "size" : 20, "query" : { "term" : { "name" : "phone" } } }
Sort
与分页几乎绑在一起的还有排序,ES允许在特定字段上添加一个或多个排序,每种排序也可以倒序。常见的asc和desc就不多说了,ES支持按数组或多值字段排序。mode选项控制选择哪个数组值来排序它所属的Document。mode选项可以有以下值:
1.min:选择最小值。
2.max:选择最大值。
3.sum:使用所有值的和作为排序值(只适用于基于数字的数组字段)。
4.avg:使用所有值的平均值作为排序值(只适用于基于数字的数组字段)。
5.median:使用所有值的中值作为排序值(只适用于基于数字的数组字段)。
在下面的示例中,字段price每个文档有多个价格。在这种情况下,结果命中将根据每个文档的平均价格按价格升序排序。
{ "query" : { "term" : { "goods" : "phone" } }, "sort" : [ {"price" : {"order" : "asc", "mode" : "avg"}} ] }
ES还支持对位于一个或多个嵌套对象中的字段进行排序。
嵌套字段支持排序有一个嵌套排序选项,具有以下属性:
1.path:定义要排序的嵌套对象。实际的sort字段必须是嵌套对象中的一个直接字段。当按嵌套字段排序时,该字段是必须要有的。
2.filter:嵌套路径中的内部对象与之匹配的筛选器,以便通过排序来考虑其字段值。常见的情况是在嵌套的过滤器或查询中重复查询/过滤器。
3.nested:与顶级嵌套相同,但适用于当前嵌套对象中的另一个嵌套路径。
在下面的示例中,case是一个类型嵌套的字段。需要指定嵌套路径;否则,ES就不知道需要在哪个嵌套级别上捕获排序值。
{ "query" : { "term" : { "product" : "chocolate" } }, "sort" : [ { "case.price" : { "mode" : "avg", "order" : "asc", "nested": { "path": "case", "filter": { "term" : { "case.color" : "grey" } } } } } ] }
地理位置排序
通过_geo_distance可以实现按照按照距离长短进行排序,下面的例子就是按照pin.location作为目标地点按照距离从近到远:
{ "sort" : [ { "_geo_distance" : { "pin.location" : [-170, 340], "unit" : "km", "mode" : "min", "distance_type" : "arc", "ignore_unmapped": true, "order" : "asc" } } ], "query" : { "term" : { "seller" : "phone" } } }
其中有几个参数需要解释下:
1.distance_type:计算距离的方式。可以是arc(弧),也可以是plane(平面,速度快,但在长距离和接近极点时不精确)。
2.mode:如果一个字段有几个地理点,默认情况下,升序排序时考虑的距离最短,降序排序时考虑的距离最长。支持的值是最小值、最大值、中值和平均值。
3.ignore_unmapped:是否应将未映射字段视为缺失值。将其设置为true相当于在字段排序中指定unmapped_type。默认为false(未映射字段导致搜索失败)。
4.unit:单位。默认是m(米)。
这篇文章主要就介绍了这两个参数。ES当然不只有这两种,只是这两种应该是最常用的,如果各位有疑问欢迎留言。
版权所属,如需转载,请注明出处:搜闲鱼