使用Elasticsearch可以对数据进行分布式搜索,根据给出的搜索条件,相关性算法对搜索结果进行打分,进而影响显示结果。
查询基本语法:
查询所有
GET /hotel1/_search #hotel1表示要查询的对象索引
{
"query": {
"match_all": {} #匹配条件:所有
}
}
#match和multi_match模糊匹配
GET /hotel1/_search
{
"query": {
"match": {
"name": "如家"
}
}
}
根据match下面的field属性进行结果的模糊匹配,先对传入参数进行分词,然后再根据分词结果在doc中进行匹配查询。
GET /hotel1/_search
{
"query": {
"multi_match": {
"query": "外滩如家酒店",
"fields": ["brand","name","business"]
}
}
}
multi_match 会匹配多个字段信息,查询效率会降低,可以事先在创建索引时通过copy_to的方式定义一个含有多个字段信息的包含属性,然后使用match去查询。
term精确查询,必须与传入的值完全相同才能匹配成功,不会对参数进行分词处理,直接进行等值匹配。
GET /hotel1/_search
{
"query": {
"term": {
"id": {
"value": "434082"
}
}
}
}
range范围查询,匹配在指定范围内的数据,gte:>= lte:<=
GET /hotel1/_search
{
"query": {
"range": {
"score": {
"gte": 10,
"lte": 30
}
}
}
}
地理位置查询
geo_distance:distance查询地理位置,以中心点为圆心,半径X公里的圆内所有值
GET /hotel1/_search
{
"query": {
"geo_distance": {
"distance": "3km",
"location": "31.220706, 121.498769"
}
}
}
geo_bounding_box:匹配在指定矩阵内的值,top_left,bottom_rigth,为矩阵的左上角和右下顶点,
lat:经度,lon:纬度
GET /hotel1/_search
{
"query": {
"geo_bounding_box":{
"location":{
"top_left":{
"lat": "31.2",
"lon": "121.5"
},
"bottom_right":{
"lat": "30.9",
"lon": "121.7"
}
}
}
}
}
在查询匹配中可以通过function_score对匹配的结果进行算分,通过算分的值对结果集展示进行重新排序。如下面查询:
GET /hotel1/_search
{
"query": {
"function_score": {
"query": {
"match": {
"name": "酒店"
}
},
"functions": [
{
"filter": {
"term": {
"brand": "如家"
}
},
"weight": 10
}
],
"boost_mode": "sum"
}
}
}
我搜索了带有“酒店”名称的所有店家,然后通过function中,对品牌为“如家”的酒店进行了weight为10的加权,加权方式为sum,表示在query查询中算出的原有分数中再加上10。最终的结果会是如家的酒店分值教其他酒店高,它会被显示在结果集的前方。
复合查询 booleanquery,它是一个或多个查询子句的组合。
must:必须匹配每一个子查询,逻辑与
should:选择性匹配子查询,逻辑或
must_not:不匹配,并且不参与算分。逻辑非
filter:必须匹配但不参与算分
查询名字中包含如家,价格不高于400,坐标在31.21,121.5 10km范围的酒店
GET /hotel1/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "如家"
}
},
{
"range": {
"price": {
"lt": 400
}
}
}
],
"filter": [
{
"geo_distance": {
"distance": "10km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
]
}
}
}
查询结果处理
对结果集排序
默认是通过相关度算分_score由高到低来进行排序的。但是也可以sort来改变排序规则。可以进行排序的字段类型有keyword,数值,地理位置坐标,日期类型等等。
排序常规字段排序
GET /hotel1/_search
{
"query": {
"match": {
"brand": "如家"
}
},
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
筛选品牌为如家的酒店,对其进行按照价格的降序排序。当添加了sort进行排序后,相关度算分_score就为null。
根据位置坐标排序
GET /hotel1/_search
{
"query": {
"match": {
"brand": "如家"
}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 31.034661,
"lon": 121.612282
},
"order": "asc",
"unit": "km"
}
}
]
}
根据提供的location坐标,由近到远排列。
结果集处理,分页
1.from+size 支持随机翻页,默认查询上限(from+size)为10000条
GET /hotel1/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_id":{
"order": "asc"
}
}
],
"from": 100,
"size": 20
}
2.search_after 分页
没有查询上限,由于他的分页原理时记录上一次最后的值,所以他不支持向前翻页。可以用于手机滚动向下的操作。search_after:记录上一次sort排序中的最后一个的值
GET /hotel1/_search
{
"size": 10,
"query": {"match_all": {}},
"sort": [
{"_id": "asc"}
],
"search_after": ["38812"]
}
3.scroll会保存上一次查询的快照在内存中,保存时间由scroll=1m指定。
POST /hotel1/_search?scroll=1m
{
"size": 100,
"query": {
"match_all": {}
},
"sort": ["_doc"]
}
返回结果会生成一个_scroll_id。下一次查询直接放上_scroll_id,就可自动滚动下100条数据。直到返回结果为null
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkQxY3ZxcE5WVHFLM1FBYnRGcnBaX2cAAAAAAAAzeRZFYTl0X202dFJxYXkyUlBjclRnQkRn=="
}
遍历完后,可以手动对快照进行销毁以节省资源
DELETE /_search/scroll
{
"scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkQxY3ZxcE5WVHFLM1FBYnRGcnBaX2cAAAAAAAAzeRZFYTl0X202dFJxYXkyUlBjclRnQkRn===="
}
结果处理,高亮显示,处理结果集加上em标签(默认)默认情况下,只突出显示包含查询匹配的字段。将require_field_match设置为false以突出显示所有字段。默认值为true。
GET /hotel1/_search
{
"query": {
"match": {
"all": "如家"
}
},
"highlight": {
"fields": {
"name":{
"pre_tags":["<em>"],
"post_tags": ["</em>"]
}
},
"require_field_match": "false"
}
}