ES常用的查询方式如下
- term系列 精确搜素
- match系列 精确搜索、模糊搜索
- exists 指定字段存在(有值)
- prefix 前缀匹配,只能是keyword类型的字段
- wildcard 通配符
- regexp 正则表达式匹配
- ids 根据id进行查询
term系列
(1)term
POST 192.168.1.9:9200/mall/_search
{
"query":{
"term":{
"goods_name":"苹果"
}
}
}
既然是查询,那都是写在"query"字段里的。
匹配机制是equals,指定字段的值要相等才算匹配,返回所有匹配的document,即精确搜索。
如果是float这种数值型,10.0、10是equals的,也算匹配的。
(2)terms
POST 192.168.1.9:9200/mall/_search
{
"query":{
"terms":{
"goods_name":["桃子","梨子"]
}
}
}
数组,只要该字段的值是数组中的任意一个元素,就认为该文档匹配。
不管是term、还是terms,都只能写一个字段,不能使用多个字段进行查询。
分析一下返回的数据
{
"took": 2, #took是take的过去式,搜索花费的时间,ms
"timed_out": false, #本次搜索是否超时
"_shards": { #分片信息
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2, #匹配的document的数量
"relation": "eq" #关系是匹配
},
"max_score": 1.0, #最大的socre,ES会给每个document分配一个score,搜索结果按score升序排列
"hits": [
{
"_index": "mall", #index
"_type": "_doc", #type
"_id": "2", #document的id
"_score": 1.0, #score
"_source": { #数据
"goods_name": "桃子",
"goods_price": 3.0,
"goods_description": "新鲜桃子,3元一斤"
}
},
{
"_index": "mall",
"_type": "_doc",
"_id": "3",
"_score": 1.0,
"_source": {
"goods_name": "梨子",
"goods_price": 5.0,
"goods_description": "新鲜桃子,5元一斤"
}
}
]
}
}
match系列
(1)match_all
POST 192.168.1.9:9200/mall/_search
{
"query":{
"match_all":{
}
}
}
返回所有的document,match_all里面不能写字段
(2)match 、match_phrase
POST 192.168.1.9:9200/mall/_search
{
"query":{
"match":{
"goods_description":"梨子"
}
}
}
如果使用text类型的字段,会使用分词器分词进行匹配,比如上面会拆分为"梨"、"子"2个字符,只要商品描述中含有“梨”字或"子"字,就认为该文档匹配,即模糊搜索。
如果match中写text之外的字段,比如写keyword类型,那效果和term一样,都是精确匹配。
match、match_phrase的效果、使用方式都一样,都只能写一个字段。
(3)multi_match
POST 192.168.1.9:9200/mall/_search
{
"query": {
"multi_match": {
"query":"苹果",
"fields":["goods_name","goods_descriptioon"]
}
}
}
multi_match可以写多个字段,只要某一个字段匹配了,就认为该文档匹配。
商品名称匹配“苹果”或商品描述匹配“苹果”,就认为该文档匹配。text类型是模糊匹配,其它类型是精确匹配。
(4)match_phrase_prefix
POST 192.168.1.9:9200/mall/_search
{
"query": {
"match_phrase_prefix": {
"goods_description":"子"
}
}
}
模糊匹配。只能写一个字段,且该字段必须是text类型。
exists
POST mall/_search
{
"query":{
"exists":{
"field": "goods_description"
}
}
}
只要指定字段有值(存在),就认为该文档匹配
prefix
POST mall/_search
{
"query":{
"prefix":{
"goods_name": "梨"
}
}
}
prefix中只能写text或keyword类型的字段。
prefix只对keyword类型的字段有效,该字段的值以指定字符串开头,就认为该文档匹配。
也能写text类型的字段,但返回值是空
wildcard
POST mall/_search
{
"query":{
"wildcard":{
"goods_name": "*瓜"
}
}
}
值可以使用通配符,*表示任意字符串,?表示任意一个字符。
wildcard是精确匹配,值必须equals才能匹配。比如"*瓜"可以匹配"冬瓜"、"哈密瓜",但匹配不了"冬瓜苗"。
regexp 正则表达式匹配
POST mall/_search
{
"query":{
"regexp":{
"goods_name":".*瓜"
}
}
}
使用的正则表达式和java中的有一点区别:不能使用\系列的规则,比如不能使用\w。
精确匹配,值要完全匹配才算。使用的字段要是text类型。
ids
POST mall/_search
{
"query":{
"ids":{
"values":[1,2,3]
}
}
}
根据id来查询,如果有该id,就返回对应的文档。
数值型id引不引都行,非数值型id需要引起来。
没有id这种查询方式,就算只查一个id,也要写成数组形式。
说明
- 使用GET、POST均可
- 返回的是所有匹配的文档
- 使用哪个字段进行匹配,可以由用户指定,前端给出搜索选项“按标题进行搜索”、“按内容进行搜索”......也可以使用固定的字段进行搜索,比如搜索商品,只按商品名称进行搜索。
值由用户输入,前端把搜索框的值传递给后台,后台查询ES。
(text字段似乎和分词器有关,如果该text字段使用内置分词器,无效,返回空;使用第三方分词器,有效,效果和keyword相同)
- 结果可分页,只返回结果集中指定的文档
POST 192.168.1.9:9200/mall/_search
{
"query": {
},
"from":0, #从结果集中的第1个文档开始
"size":20 #取20个文档。结果集中的文档是按score升序排列的。
}