Java ElasticSearch:(六)Search 搜索详解-5500字匠心出品

1.搜索学习测试数据

PUT test_search
{
	"mappings": {
		"test_type" : {
			"properties": {
				"dname" : {
					"type" : "text",
					analyzer": "standard"
				},
				"ename" : {
					"type" : "text",
					"analyzer": "standard"
				},
				"eage" : {
					"type": "long"
				},
				"hiredate" : {
					"type": "date"
				},
				"gender" : {
					"type" : "keyword"
				}
			}
		}
	}
}

POST test_search/test_type/_bulk
{ "index": {}}
{ "dname" : "Sales Department", "ename" : " 张 三 ", "eage":20, "hiredate" : "2019-01-01", "gender" : "男性" }
{ "index": {}}
{ "dname" : "Sales Department", "ename" : " 李 四 ", "eage":21, "hiredate" : "2019-02-01", "gender" : "男性" }
{ "index": {}}
{ "dname" : "Development Department", "ename" : " 王 五 ", "eage":23, "hiredate" : "2019-01-03", "gender" : "男性" }
{ "index": {}}
{ "dname" : "Development Department", "ename" : " 赵 六 ", "eage":26, "hiredate" : "2018-01-01", "gender" : "男性" }
{ "index": {}}
{ "dname" : "Development Department", "ename" : " 韩 梅 梅 ", "eage":24, "hiredate" : "2019-03-01", "gender" : "女性" }
{ "index": {}}
{ "dname" : "Development Department", "ename" : " 钱 虹 ", "eage":29, "hiredate" : "2018-03-01", "gender" : "女性" }

2.query string search

  • search 的参数都是类似 http 请求头中的字符串参数提供搜索条件的。
    GET [/index_name/type_name/]_search[?parameter_name=parameter_value&…]

2.1 全搜索

  • timeout 参数:是超时时长定义。代表每个节点上的每个 shard 执行搜索时最多耗时多久。不会影响响应的正常返回。只会影响返回响应中的数据数量
  • 如:索引 a 中,有 10 亿数据。存储在 5 个 shard 中,假设每个 shard 中 2 亿数据,执行全数据搜索的时候,需要耗时 1000 毫秒。定义 timeout 为 10 毫秒,代表的是 shard 执行 10 毫秒,搜索出多少数据,直接返回。
  • 在商业项目中,是禁止全数据搜索的。必须指定搜索的索引,类型和关键字。如果没有指定索引或类型,则代表开发目的不明确,需要重新做用例分析。如果没有关键字,称为索引内全搜索,也叫魔鬼搜索。
  • 语法:
    GET [索引名/类型名/]_search?timeout=10ms
  • 结果:
{
	"took": 144, #请求耗时多少毫秒
	timed_out": false, #是否超时。默认情况下没有超时机制,也就是客户端等待 ElasticSearch 搜索结束(无论执行多久),提供超时机制的话,ElasticSearch 则在指定时长内处理搜索,在指定时长结束的时候,将搜索的结果直接返回(无论是否搜索结束)。指定超时的方式是传递参数,参数单位是:毫秒-ms。秒-s。分钟-m。
	"_shards": {
		"total": 1, #请求发送到多少个 shard 上
		"successful": 1,#成功返回搜索结果的 shard
		"skipped": 0, #停止服务的 shard
		"failed": 0 #失败的 shard
	},
	"hits": {
		"total": 1, #返回了多少结果
		"max_score": 1, #搜索结果中,最大的相关度分数,相关度越大分数越高,_score 越大,排位越靠前
		"hits": [ #搜索到的结果集合,默认查询前 10 条数据。
			{
				"_index": "test_index", #数据所在索引
				"_type": "my_type", #数据所在类型
				"_id": "1", #数据的 id
				"_score": 1, #数据的搜索相关度分数
				"_source": { # 数据的具体内容。
					"field": "value"
				}
			}
		]
	}
}

2.2 multi index 搜索

  • 所谓的 multi-index 就是从多个 index 中搜索数据。相对使用较少,只有在复合数据搜索的时候,可能出现。一般来说,如果真使用复合数据搜索,都会使用_all。
  • 如:搜索引擎中的无条件搜索。(现在的应用中都被屏蔽了。使用的是默认搜索条件,执行数据搜索。 如: 电商中的搜索框默认值, 搜索引擎中的类别)
  • 无条件搜索,在搜索应用中称为“魔鬼搜索”,代表的是,搜索引擎会执行全数据检索,效率极低,且对资源有非常高的压力。
  • 语法:
GET _search

GET 索引名 1,索引名 2/_search # 搜索多个 index 中的数据

GET 索引名/类型名/_search # 所属一个 index 中 type 的数据

GET prefix_*/_search # 通配符搜索
GET *_suffix/_search

GET 索引名 1,索引名 2/类型名/_search # 搜索多个 index 中 type 的数据

GET _all/_search # _all 代表所有的索引

2.3 条件搜索

  • query string search 搜索是通过 HTTP 请求的请求头传递参数的,默认的 HTTP 请求头字符集是 ISO-8859-1,请求头传递中文会有乱码
  • 语法:
GET 索引名/_search?q=字段名:搜索条件

2.4 分页搜索

  • 默认情况下,ElasticSearch 搜索返回结果是 10 条数据。从第 0 条开始查询
  • 语法:
GET 索引名/_search?size=10 # size 查询数据的行数

GET 索引名/_search?from=0&size=10 # from 从第几行开始查询,行号从 0 开始。

2.5 +/-搜索

  • 语法:
GET 索引名/_search?q=字段名:条件

GET 索引名/_search?q=+字段名:条件

GET 索引名/_search?q=-字段名:条件
  • +:和不定义符号含义一样,就是搜索指定的字段中包含 key words 的数据
  • -: 与+符号含义相反,就是搜索指定的字段中不包含 key words 的数据

2.6 排序

  • 语法:GET 索引名/_search?sort=字段名:排序规则
  • 排序规则: asc(升序) | desc(降序)
GET test_search/_search?sort=eage:asc

GET test_search/_search?sort=eage:desc

3.query DSL

  • DSL - Domain Specified Language , 特殊领域的语言。
  • 请求参数是请求体传递的。在 ElasticSearch 中,请求体的字符集默认为 UTF-8。
  • 语法格式:
GET 索引名/_search
{
	"command":{ "parameter_name" : "parameter_value"}
}

3.1 查询所有数据

GET 索引名/_search
{
	"query" : { "match_all" : {} }
}

3.2 match search

  • 全文检索。要求查询条件拆分后的任意词条与具体数据匹配就算搜索结果。
GET 索引名/_search
{
	"query": {
		"match": {
			"字段名": "搜索条件"
		}
	}
}

3.3 phrase search

  • 短语检索。要求查询条件必须和具体数据完全匹配才算搜索结果。其特征是:1-搜索条件不做任何分词解析;2-在搜索字段对应的倒排索引(正排索引)中进行精确匹配,不再是简单的全文检索
GET 索引名/_search
{
	"query": {
		"match_phrase": {
			"字段名": "搜索条件"
		}
	}
}

3.4 range

  • 范围比较搜索
GET 索引名/类型名/_search
{
	"query" : {
		"range" : {
			"字段名" : {
				"gt" : 搜索条件 1,
				"lte" : 搜索条件 2
			}
		}
	}
}

3.5 term

  • 词组比较,词组搜索
  • 忽略搜索条件分词,在 ElasticSearch 倒排索引中进行精确匹配。
GET 索引名/类型名/_search
{
	"query" : {
		"term" : {
			"字段名": "搜索条件"
		}
	}
}

GET 索引名/类型名/_search
{
	"query" : {
		"terms" : {
			"字段名": ["搜索条件 1", "搜索条件 2"]
		}
	}
}

3.6 多条件复合搜索

  • 在一个请求体中,有多个搜索条件,就是复合搜索。如:搜索数据,条件为部门名称是 Sales Department,员工年龄在 20 到 26 之间,部门员工姓名叫张三。上述条件中,部门名称为可选条件,员工年龄必须满足要求,部门员工姓名为可选要求。这种多条件搜索就是符合搜索
GET 索引名/类型名/_search
{
	"query": {
		"bool": {
			"must": [ #数组中的多个条件必须同时满足
				{
					"range": {
						"字段名": {
							"lt": 条件
						}
					}
				}
			],
			"must_not":[ #数组中的多个条件必须都不满足
				{
					"match": {
						"字段名": "条件"
					}
				},
				{
					"range": {
						"字段名": {
							"gte": "搜索条件"
						}
					}
				}
			]
			"should": [# 数组中的多个条件有任意一个满足即可。
				{
					"match": {
						"字段名": "条件"
					}
				},
				{
					"range": {
						"字段名": {
							"gte": "搜索条件"
						}
					}
				}
			]
		}
	}
}

3.7 排序

  • 在 ElasticSearch 的搜索中,默认是使用相关度分数实现排序的。可以通过搜索语法实现定制化排序
GET 索引名/类型名/_search
{
	"query": {
		[搜索条件]
	},
	"sort": [
		{
			"字段名 1": {
				"order": "asc"
			}
		},
		{
			"字段名 2": {
				"order": "desc"
			}
		}
	]
}
  • 注意:在 ElasticSearch 中,如果使用 text 类型的字段作为排序依据,会有问题。ElasticSearch 需要对 text 类型字段数据做分词处理。如果使用 text 类型字段做排序,ElasticSearch 给出的排序结果未必友好,毕竟分词后,先使用哪一个单词做排序都是不合理的。
  • 所以 ElasticSearch 中默认情况下不允许使用 text 类型的字段做排序,如果需要使用字符串做结果排序,则可使用 keyword 类型字段作为排序依据,因为 keyword 字段不做分词处理

3.8 分页

  • DSL 分页也是使用 from 和 size 实现的
GET 索引名称/_search
{
	"query":{
		"match_all":{}
	},
	"from": 起始下标,
	"size": 查询记录数
}

3.9 highlight display

  • 在搜索中,经常需要对搜索关键字做高亮显示,这个时候就可以使用 highlight 语法。
  • 语法:
GET 索引名/_search
{
	"query": {
		"match": {
			"字段名": "条件"
		}
	},
	"highlight": {
		"fields": {
			"要高亮显示的字段名": {
				"fragment_size": 5, #每个分段长度,默认 20
				"number_of_fragments": 1 #返回多少个分段,默认 3
			}
		},
		"pre_tags": ["前缀"],
		"post_tags": ["后缀"]
	}
}
  • 演示案例:
GET test_search/_search
{
	"query": {
		"bool": {
			"should": [
				{
					"match": {
						"dname": "Development department"
					}
				}{
					"match": {
						"gender": "男性"
					}
				}
			]
		}
	},
	"highlight": {
		"fields": {
			"dname": {
				"fragment_size": 20
				"number_of_fragments": 1
			},
			"gender": {
				"fragment_size": 20,
				"number_of_fragments": 1
			}
		},
		"pre_tags":["<span style='color:red'>"],
		"post_tags":["</span>"]
	},
	"from": 2,
	"size": 2
}
  • fragment_size:代表字段数据如果过长,则分段,每个片段数据长度为多少。长度不是字符数量,是 ElasticSearch 内部的数据长度计算方式。默认不对字段做分段
  • number_of_fragments:代表搜索返回的高亮片段数量,默认情况下会将拆分后的所有片段都返回
  • pre_tags:高亮前缀
  • post_tags:高亮后缀
  • 很多搜索结果显示页面中都不会显示完整的数据,这样在数据过长的时候会导致页面效果不佳 ,都会按照某一个固定长度来显示搜索结果,所以 fragment_size 和 number_of_fragments 参数还是很常用的。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

地球村公民

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值