从这篇文章开始,我们要进入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当然不只有这两种,只是这两种应该是最常用的,如果各位有疑问欢迎留言。
版权所属,如需转载,请注明出处:搜闲鱼