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 参数还是很常用的。