Elasticsearch之DSL搜索(Domain Specific Language)

1. 查询所有文档 match_all

关键字:match_all

请求方式:POST

请求接口:http://localhost/shop/_doc/_search

{
    "query": {
        "match_all": {}                  # 查询所有文档
    },
    "_source": ["id", "nickname", "age"] # 指定要查询的字段
}

2. 分页查询 from、size 

关键字:from、size 

请求方式:POST

请求接口:http://localhost/shop/_doc/_search

{
    "query": {
        "match_all": {}                  # 查询所有文档
    },
    "from":0,
    "size":10,
    "_source": ["id", "nickname", "age"] # 指定要查询的字段
}

3. term精确搜索与match分词搜索

请求方式:POST

请求接口:http://localhost/shop/_doc/_search

{
    "query":{
        "match":{
            "desc":"游戏机"   # 会将用户输入的搜索词进行分词;再用分词去和文档进行匹配        
        }
    },
    "_source":["id", "nickname", "desc"]
}
{
    "query":{
        "term":{
            "desc":"游戏机"   # 不会将用户输入的搜索词进行分词,直接用完整的搜索词和文档进行匹配
        }
    },
    "_source":["id", "nickname", "desc"]
}

terms 多词语匹配(这里比term多了一个s):

  • 不将用户输入的关键字进行分词

  • 当文档中出现 其中一个关键词的时候, 就能搜索出来

{
    "query": {
        "terms": {
            "desc": ["游戏机", "学习", "骚年"]
        }
    }
}

4. match_phrase 短语匹配

  • match:分词后只要有匹配就返回
  • match_phrase:分词结果必须在文档分词中都包含,而且顺序必须相同,而且必须都是连续的。(可使用slop实现不连续, slop:允许词语间跳过的最多数量)
{
    "query": {
        "match_phrase": {
            "desc": {
                "query":"大学 毕业 研究生",
                "slop":2
            }
        }
    }
}

5. match 扩展:operator、minimum_should_match、ids

operator:

  • or:搜索内容分词后,只要存在一个词语匹配就展示结果
  • and:搜索内容分词后,都要满足词语匹配
{
    "query": {
        "match": {
            "desc": "xbox游戏机"
        }
    }
}
# 等同于
{
    "query": {
        "match": {
            "desc": {
                "query": "xbox游戏机",
                "operator": "or"  # 默认是 or
            }
        }
    }
}
# 相当于 select * from shop where desc='xbox' or|and desc='游戏机'

minimum_should_match: 最低匹配精度,至少有[分词后的词语个数]x百分数,得出一个数据值取整。举个例子:当前属性设置为"70%",若一个用户查询检索内容分词后有10个词语,那么匹配度按照 10x70%=7,则desc中至少需要有7个词语匹配,就展示;若分词后有8个,则 8x70%=5.6,则desc中至少需要有5个词语匹配,就展示。minimum_should_match后面也可以直接写数值

{
    "query": {
        "match": {
            "desc": {
                "query": "女友生日送我好玩的xbox游戏机",
                "minimum_should_match": "60%"  # 也可以直接写 5
            }
        }
    }
}

根据文档主键ids搜索

    {
        "query":{
            "ids":{
                "type":"_doc",
                "values":["1001","1002","1003"]
            }
        }
    }

6. multi_match/boost

multi_match:满足使用match在多个字段中进行查询的需求

    {
        "query":{
            "multi_match":{
                "query":"游戏机",
                "fields":["nickname","desc"]
            }
        }
    }

boost:权重,为某个字段设置权重,权重越高,文档相关性得分就越高。通常来说搜索商品名称要比商品简介的权重更高,所以可以给商品名称设置高权重。

   {
        "query":{
            "multi_match":{
                "query":"游戏机",
                "fields":["desc","nickname^10"]
            }
        }
    }

nickname^10 代表搜索提升10倍相关性,也就是说用户搜索的时候其实以这个nickname为主,desc为辅,nickname的匹配相关度权重比例就提高了。

7. 布尔查询—多重组合查询 bool

    {
        "query":{
            "bool":{
                "must":[],
                "should":[],
                "must_not":[]
            }
        }
    }
  • must 相当于数据库中的 AND, must中的内容必须要同时满足

  • should 相当于数据库中的 OR, should中的内容满足其一即可

  • must_not 相当于数据库中的 != ,must_not中的内容必须都保证不满足

{
    "query": {
        "bool": {
            "must": [
                {
                    "multi_match": {
                        "query": "游戏机",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                    "term": {
                        "sex": 1
                    }
                },
                {
                    "term": {
                        "birthday": "1996-01-14"
                    }
                }
            ],
            "should": [
                {
                    "multi_match": {
                        "query": "学习",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                	"match": {
                		"desc": "游戏"
                	}	
                },
                {
                    "term": {
                        "sex": 0
                    }
                }
            ],
            "must_not": [
                {
                    "multi_match": {
                        "query": "工作",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                	"match": {
                		"desc": "衣服"
                	}	
                },
                {
                    "term": {
                        "sex": 0
                    }
                }
            ]
        }
    }
}

 8. 为指定词语加权 boost

特殊场景下,某些词语可以单独加权,这样可以使得该词语对应的查询结果排得更加靠前。

    {
        "query":{
            "bool":{
                "should":[
                    {
                        "match":{
                            "desc":{
                                "query":"游戏机",
                                "boost":2
                            }
                        }
                    },
                    {
                        "match":{
                            "desc":{
                                "query":"律师",
                                "boost":10
                            }
                        }
                    }
                ]
            }
        }
    }

9. 过滤器 post_filter

 post_filter元素是一个顶层元素,只会对搜索结果进行过滤。不会计算数据的匹配度相关性分数,不会根据分数去排序,query则相反,会计算分数,也会按照分数去排序。

使用场景:

  • query:根据用户搜索条件检索匹配记录
  • post_filter:用于查询后,对结果数据的筛选 其中的一些参数:gte:大于等于;lte:小于等于;gt:大于;lt:小于;
    {
        "query":{
            "match":{
                "desc":"游戏机"
            }
        },
        "post_filter":{
            "range":{
                "money":{
                    "gte":55,
                    "lt":1000
                }
            }
        }
    }

 10. 排序 sort

  • es搜索结果默认是按照 "_score" 关键字的文档权重分数进行排序的;可以使用 sort 指定按照某个字段进行排序

  • sort 支持组合排序, 先根据第一个属性进行排序, 排完序如果有重复的再根据下一个属性进行排序

  • 升序 asc, 降序 desc

    {
        "query":{
            "match":{
                "desc":"游戏机"
            }
        },
        "post_filter":{
            "range":{
                "money":{
                    "gte":55,
                    "lt":1000
                }
            }
        },
        "sort":[
            {
                "age":"desc"
            },
            {
                "birthday":"desc"
            }
        ]
    }

11. 高亮显示 highlight

{
    "query":{
        "match":{
            "desc":"游戏机"
        }
    },
    "highlight":{
        "pre_tags":["<span>"],   # 指定高亮显示那部分词语的前标签,默认是使用 <em>标签将 关键词包裹起来
        "post_tags":["</span>"], # 指定高亮显示那部分词语的后标签
        "fields":{
            "desc":{}
        }
    }
}

12. 提升搜索量

es查询默认查询数据不能超过10000条,可以通过修改设置,突破这个限制。可通过设置index.max_result_window来突破10000数据限制。

查看设置:GET     http://localhost:9200/index_demo/_settings

 

修改设置:PUT     http://localhost:9200/index_demo/_settings

13. 滚动搜索 scroll

一次性查询1万+数据,往往会造成性能影响,因为数据量太多了。这个时候可以使用滚动搜索,也就是 scroll。

滚动搜索可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个scroll_id,相当于一个 锚标记 ,随后再次滚动搜索会需要上一次搜索的 锚标记 ,根据这个进行下一次的搜索请求。每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的,搜索的内容还是快照中的数据。

第一次搜索:

接口:POST    http://localhost:9200/index_demo/_search?scroll=1m

  • scroll=1m,相当于是一个session会话时间,搜索保持的上下文时间为1分钟。
{
    "query": { 
    	"match_all": {
    	}
    },  
    "sort" : ["_doc"], 
    "size":  5
}

第二次就可以用 scroll_id 进行搜索了,注意查询接口也不一样了

接口:POST       http://localhost:9200/_search/scroll

{
    "scroll_id":"DnF1ZXJ5VGhlbkZldGNoAgAAAAAAAAAyFkVDMDBWQ29qU05hT2YzMkppV3FlSFEAAAAAAAAAMxZFQzAwVkNvalNOYU9mMzJKaVdxZUhR",
    "scroll":"1m"
}

14. 批量操作: bulk

{ action: { metadata }}\n
{ request body        }\n
{ action: { metadata }}\n
{ request body        }\n
...
  • { action: { metadata }} 代表批量操作的类型,可以是新增、删除或修改 
  • \n 是每行结尾必须填写的一个规范,每一行包括最后一行都要写,用于es的解析 
  • ​{ request body } 是请求body,增加和修改操作需要,删除操作则不需要 

action 必须是以下选项之一:

  • create:如果文档不存在,那么就创建它。存在会报错。发生异常报错不会影响其他操作。
  • index:创建一个新文档或者替换一个现有的文档。
  • update:部分更新一个文档。
  • ​delete:删除一个文档。

metadata 中需要指定要操作的文档的 _index 、 _type 和 _id,不过_index 、 _type 也可以在url中指定。

(1)create新增文档数据,在metadata中指定index以及type,也可以将index以及type放入url中

接口:POST    http://localhost:9200/_bulk

{"create":{"_index":"index_demo", "_type":"_doc", "_id":"1001"}}
{"id":"123", "nickname":"明天你好"}
{"create":{"_index":"index_demo", "_type":"_doc", "_id":"1002"}}
{"id":"234", "nickname":"明天你不好"}
{"create":{"_index":"index_demo", "_type":"_doc", "_id":"1003"}}
{"id":"3455", "nickname":"明天你很好"}

(2)index创建,已有文档id会被覆盖,不存在的id则新增

接口:POST     http://localhost:9200/index_demo/_doc/_bulk

{"index":{"_id":"1001"}}
{"id":"999", "nickname":"我是你哥"}
{"index":{"_id":"1004"}}
{"id":"998", "nickname":"我是你大哥"}
{"index":{"_id":"1005"}}
{"id":"997", "nickname":"我是你大爷"}

 (3)update更新

接口:POST     http://localhost:9200/index_demo/_doc/_bulk

{"update":{"_id":"1001"}}
{"doc":{"id":"111", "nickname":"全部更新中"}}
{"update":{"_id":"1002"}}
{"doc":{"id":"222"}}
{"update":{"_id":"1003"}}
{"doc":{"nickname":"部分更新中"}}

(4)delete删除

接口:POST     http://localhost:9200/index_demo/_doc/_bulk

{"delete":{"_id":"1001"}}
{"delete":{"_id":"1002"}}
{"delete":{"_id":"1003"}}

(5)综合各种操作

接口:POST     http://localhost:9200/index_demo/_doc/_bulk

{"create":{"_id":"1001"}}
{"id":"123", "nickname":"明天你好"}
{"index":{"_id":"1002"}}
{"id":"999", "nickname":"我是你哥"}
{"update":{"_id":"1004"}}
{"doc":{"id":"111", "nickname":"全部更新中"}}
{"delete":{"_id":"1005"}}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值