ES
在搜索上对外开放了 Resultful API
, 方便各个语言调用,那么他调用有两种方式,一种就是单纯将搜索的参数放到url
上,还有就是可以放到Request Body
里面,我们来依次看看。
URL Search 路由携带参数搜索
GET movies/_search?q=love&df=title&sort=year:asc&from=0&size=10 { "profile": "true" }
我们来对上面的url
分析一下,movies
是索引,_search
表示我们要进行搜索
- q 指定查询内容
- df 指定查询字段
- sort 指定字段排序
- from 偏移量
- size 获取数据量 与from联合使用 做分页的
- 下面有个profile 是为了查询执行过程
- or 查询
# 等效为or查询 GET movies/_search?q=title:(Beautiful OR Mind) { "profile": "true" }
- and 查询
GET movies/_search?q=title:(Beautiful AND Mind) { "profile": "true" }
- 范围查询
GET movies/_search?q=year:[2018 TO 2019] { "profile": "true" }
[] 为闭区间,{} 为开区间
year:[2018 TO 2019],查询时间在2018-2019年的电影
- 模糊查询
"Avengers War"~2 ,Avengers
和 War
之间有两个 term
,匹配 Avengers: Infinity War - Part I
,不能匹配 Avengers: War
。
GET /movies/_search?q=title:"Avengers War"~2 { "profile": "true" }
Request Body Search 请求体携带Json搜索
其实在高阶使用方法上只有 Request Body Search
才能实现,所以也是推荐使用这种方法查询学习。
POST test/_search { "profile": "true", "_source": ["name", "date"], # 指定展示的字段 "from": 0, # 分页偏移 "size": 20, # 总共获取20 "sort": [ # 排序 { "date": { "order": "desc" } } ], "query": { "match_all": {} # 查询所有文档 } }
Match 查询表达式
POST test/_search { "query": { "match": { "name": "王 五" } } }
这样会匹配到name
字段中带王
或者带五
的文档,类似于 OR
关系,如果你只需要王五的话,可以添加and
操作
POST test/_search { "query": { "match": { "name": { "query": "王五", "operator": "and" } } } }
Match Phrase
通过使用 query-match_phrase
实现 Phrase
查询,query
的词必须按照顺序排列,slop
实现模糊查询,slop=1
,表示中间可以有一个字符
POST test/_search { "query": { "match_phrase": { "tag": { "query": "java php" } } } }
这个顺序就不能反,否则查询不到。那如果需要查tag
为java,laravel
中间是随意字符的话就需要slop
这样就是实现中间模糊查询。
Request Body Search中间 match, match_phrase, term的区别
- term
term
结构化字段查询,匹配一个值,且输入的值不会被分词器分词。
{ "query":{ "term":{ "foo": "hello world" } } }
那么只有在字段中存储了hello world
的数据才会被返回,如果在存储时,使用了分词,原有的文本“I say hello world”
会被分词进行存储,不会存在“hello world”
这整个词,那么不会返回任何值。
但是如果使用“hello”
作为查询条件,则只要数据中包含“hello”
的数据都会被返回,分词对这个查询影响较大。
- match_phase
查询确切的语句,在对查询字段定义了分词器的情况下,会使用分词器对输入进行分词,然后返回满足下述两个条件的文档
- match_phase中的所有term都出现在待查询字段之中
- 待查询字段之中的所有term都必须和match_phase具有相同的顺序
{ "foo":"I just said hello world" } { "foo":"Hello world" } { "foo":"World Hello" }
使用match_phase:
{ "query": { "match_phrase": { "foo": "Hello World" } } }
会返回前两条文档。
- match
模糊匹配,先对输入进行分词,对分词后的结果进行查询,文档中只要包含match
查询条件的一部分就会返回
- query_string
query_string
语法查询,同match_phase
的相同点在于,输入的查询条件会被分词,但是不同之处在与文档中的数据可以不用和query_string
中的查询条件有相同的顺序。