search api
- uri search
- 在uri中使用查询参数
- request body search
- 使用elasticsearch提供的,基于json格式的更加完备的query domain specific language (dsl)
指定查询的索引
语法 | 范围 |
---|---|
/_search | 集群上所有的索引 |
/index1/_search | index1 |
/index1,index2/_search | index1和index2 |
/index*/_search | 以index开头的索引 |
uri查询
- 使用“q”,指定查询的字符串
-
“query string syntax”,kv键值对
request body查询
搜索response
搜索的相关性 relevance
- 搜索是用户和搜索引擎的对话
- 用户关心的是搜索结果的相关性
- 是否可以找到所有相关的内容
- 有多少不相关的内容被返回了
- 文档的打分是否合理
- 结合业务需求,平衡结果排名
web搜索
- page rank算法
- 不仅仅是内容,更重要的是内容的可信度
电商搜索
- 搜索殷勤扮演销售的角色
- 提高用户的购物体验
- 提升网站的销售业绩
- 去库存
衡量相关性
- information retrieval
- precision 查准率,尽可能返回较少的无关文档
- recall 查全率,尽量发挥较多的相关文档
- ranking,是否能够按照相关度进行排序?
#URI Query
GET kibana_sample_data_ecommerce/_search?q=customer_first_name:Eddie
GET kibana*/_search?q=customer_first_name:Eddie
GET /_all/_search?q=customer_first_name:Eddie
#REQUEST Body
POST kibana_sample_data_ecommerce/_search
{
"profile": true,
"query": {
"match_all": {}
}
}
uri search 通过uri query 实现搜索
get /movie/_search?q=2012&df=title&sort=year:desc&from=0&size=10&timeou=1s
{
"profile":true
}
- q 指定查询语句,使用query string syntax
- df 默认字段,不指定时,会对所有的字段进行查询
- sort 排序,from和size用于分页
- profile 可以查看查询是如何执行的
query string syntax
-
指定字段 vs 泛查询
- q=title:2012 / q-2012
-
term vs phrase
- beautiful mind 等效于 beautiful or mind
- "beautiful mind",等效于 beantiful and mind。phrase查询,还要求前后的顺序保持一致
-
分组和引号
- title:(beautiful and mind)
- title="beautiful mind"
-
布尔操作
- AND / OR / NOT 或者 && / || / !
- 必须大写
- title:(matrix NOT reloaded)
- AND / OR / NOT 或者 && / || / !
-
分组
-
+
表示 must -
-
表示 must_not - title:(+matrix -reloaded)
-
-
范围查询
- 区间表示:
[]
闭区间,{}
开区间- year:{2019 TO 2018]
- year:[* TO 2018]
- 区间表示:
-
算数符号
- year:>2010
- year:(>2010 && <=2018)
- year:(+>2010 +<=2018)
-
通配符查询(通配符查询效率低,占用内存大,不建议使用。特别是放在最前面)
-
?
代表一个字符,*
代表0或者多个字符- title:mi?d
- title:be*
-
-
正则表达(
尝试无效
)- title:[bt]oy
-
模糊匹配与近似查询
- title:beautifl~1
- title:"lord rings"~2
uri 查询示例
#基本查询
GET /movies/_search?q=2012&df=title&sort=year:desc&from=0&size=10&timeout=1s
#带profile
GET /movies/_search?q=2012&df=title
{
"profile":"true"
}
#泛查询,正对_all,所有字段
GET /movies/_search?q=2012
{
"profile":"true"
}
#指定字段
GET /movies/_search?q=title:2012&sort=year:desc&from=0&size=10&timeout=1s
{
"profile":"true"
}
# 查找美丽心灵, Mind为泛查询
GET /movies/_search?q=title:Beautiful Mind
{
"profile":"true"
}
# 泛查询
GET /movies/_search?q=title:2012
{
"profile":"true"
}
#使用引号,Phrase查询
GET /movies/_search?q=title:"Beautiful Mind"
{
"profile":"true"
}
#分组,Bool查询
GET /movies/_search?q=title:(Beautiful Mind)
{
"profile":"true"
}
#布尔操作符
# 查找美丽心灵
GET /movies/_search?q=title:(Beautiful AND Mind)
{
"profile":"true"
}
# 查找美丽心灵
GET /movies/_search?q=title:(Beautiful NOT Mind)
{
"profile":"true"
}
# 查找美丽心灵 %2B == +
GET /movies/_search?q=title:(Beautiful %2BMind)
{
"profile":"true"
}
#范围查询 ,区间写法
GET /movies/_search?q=title:beautiful AND year:[2002 TO 2018%7D
{
"profile":"true"
}
#通配符查询
GET /movies/_search?q=title:b*
{
"profile":"true"
}
#模糊匹配&近似度匹配
GET /movies/_search?q=title:beautifl~1
{
"profile":"true"
}
GET /movies/_search?q=title:"Lord Rings"~2
{
"profile":"true"
}
request body search
一些高阶的使用方法只能通过request body search进行
将查询语句通过http request body发送给elasticsearch
-
query dsl
-
分页
- from 从10开始,返回20个结果,默认从0开始
- elasticsearch支持的分页最大值是2^31-1,也就是2147483647,通过设置 index.max_result_window 可以修改
-
获取靠后的翻页成本比较高
-
_source filtering
- 如果 _source 没有存储,那就只返回匹配的文档的元数据
- _source支持使用通配符_source["name", "desc"]
-
脚本字段
-
用例:订单中有不同的汇率,需要结合汇率时,订单价格进行排序
-
-
使用查询表达式 match
-
短语查询 match phrase
#ignore_unavailable=true,可以忽略尝试访问不存在的索引“404_idx”导致的报错
#查询movies分页
POST /movies,404_idx/_search?ignore_unavailable=true
{
"profile": true,
"query": {
"match_all": {}
}
}
POST /kibana_sample_data_ecommerce/_search
{
"from":10,
"size":20,
"query":{
"match_all": {}
}
}
#对日期排序
POST kibana_sample_data_ecommerce/_search
{
"sort":[{"order_date":"desc"}],
"query":{
"match_all": {}
}
}
#source filtering
POST kibana_sample_data_ecommerce/_search
{
"_source":["order_date"],
"query":{
"match_all": {}
}
}
#脚本字段
GET kibana_sample_data_ecommerce/_search
{
"script_fields": {
"new_field": {
"script": {
"lang": "painless",
"source": "doc['order_date'].value+'hello'"
}
}
},
"query": {
"match_all": {}
}
}
POST movies/_search
{
"query": {
"match": {
"title": "last christmas"
}
}
}
POST movies/_search
{
"query": {
"match": {
"title": {
"query": "last christmas",
"operator": "and"
}
}
}
}
POST movies/_search
{
"query": {
"match_phrase": {
"title":{
"query": "one love"
}
}
}
}
POST movies/_search
{
"query": {
"match_phrase": {
"title":{
"query": "one love",
"slop": 1
}
}
}
}
query string & simple query string
-
query string query
-
类似uri query
-
-
simple query string query
- 类似query string,但是会忽略错误的语法,同时只支持部分查询语法
- 不支持 AND OR NOT,会当做字符串处理
- term之间默认的关系是OR,可以指定operator
- 支持部分逻辑
-
+
代替AND
-
|
代替OR
-
-
代替NOT
-
Query & Simple Query String Query
PUT /users/_doc/1
{
"name":"Ruan Yiming",
"about":"java, golang, node, swift, elasticsearch"
}
PUT /users/_doc/2
{
"name":"Li Yiming",
"about":"Hadoop"
}
POST users/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "Ruan AND Yiming"
}
}
}
POST users/_search
{
"query": {
"query_string": {
"fields":["name","about"],
"query": "(Ruan AND Yiming) OR (Java AND Elasticsearch)"
}
}
}
#Simple Query 默认的operator是 Or
POST users/_search
{
"query": {
"simple_query_string": {
"query": "Ruan AND Yiming",
"fields": ["name"]
}
}
}
POST users/_search
{
"query": {
"simple_query_string": {
"query": "Ruan Yiming",
"fields": ["name"],
"default_operator": "AND"
}
}
}
GET /movies/_search
{
"profile": true,
"query":{
"query_string":{
"default_field": "title",
"query": "Beafiful AND Mind"
}
}
}
# 多fields
GET /movies/_search
{
"profile": true,
"query":{
"query_string":{
"fields":[
"title",
"year"
],
"query": "2012"
}
}
}
GET /movies/_search
{
"profile":true,
"query":{
"simple_query_string":{
"query":"Beautiful +mind",
"fields":["title"]
}
}
}