前言

有时我们在搜索电影的时候,包含了多个条件,比如主演是周星驰,打分8分以上,上映时间是1990年~2001年的,那么Elasticsearch又该如何帮我们做查询呢?这里我们可以用 bool 查询来实现需求。这种查询将多查询组合在一起,成为用户自己想要的 bool 查询。

bool 查询

一个 bool 查询,可以包含一个或多个查询语句进行组合。

有4种参数

  • must:文档必须匹配这些条件才能被包含进来。贡献算分。
  • should:文档选择性匹配,如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。贡献算分。
  • must_not:文档必须不匹配这些条件才能被包含进来。
  • filter:必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。不贡献算分。

基本语法

  • bool 里面的子查询继续嵌套 bool 查询
  • 子查询可以以任意顺序出现
  • 如果没有 must 语句,那么至少需要能够匹配其中的一条 should 语句。但如果存在至少一条 must 语句,则对 should 语句的匹配没有要求。
  • must等可以跟一个对象(“{}”),也可以跟数组(“[]”)
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }}
],
"filter": {
"bool": {
"must": [
{ "range": { "date": { "gte": "2014-01-01" }}},
{ "range": { "price": { "lte": 29.99 }}}
],
"must_not": [
{ "term": { "category": "ebooks" }}
]
}
}
}
}

一个航班查询的例子,搜索去往美国的,当地天气是晴朗的,不从日本出发的,票价小于等于1000的航班。

GET kibana_sample_data_flights/_search
{
"size": 5,
"query": {
"bool": {
"must": [
{
"term": {
"DestCountry": "US"
}
},
{
"term": {
"DestWeather": "Sunny"
}
}
],
"must_not": {
"term": {
"OriginCountry": "JP"
}
},
"filter": {
"range": {
"AvgTicketPrice": {
"lte": 1000
}
}
}
}
}
}

控制相关性

那么多个字段的查询,我们该如何影响其相关性的算分呢?

层级嵌套

同一层级下的字段是竞争关系,具有相同权重,可以通过嵌套改变对算分的影响。

GET animals/_search
{
"query": {
"bool": {
"should": [
{"term": {"text": "brown"}},
{"term": {"text": "red"}},
{"term": {"text": "quick"}},
{"term": {"text": "dog"}}
]
}
}
} GET animals/_search
{
"query": {
"bool": {
"should": [
{"term": {"text": "brown"}},
{"term": {"text": "red"}},
{"bool": {
"should": [
{"term": {"text": "quick"}},
{"term": {"text": "dog"}}
]
}
}
]
}
}
}

boosting

控制字段的权重,可以使用boosting,默认值是1,可正可负。

  • 当boost>1时,打分的相关性相对提升
  • 当0<boost<1时,打分的相关性相对降低
  • 当boost<0时,贡献负分

精简语法,可以在match里面指定boost,比如上面的航班信息DestCountry部分字段设置权重。

GET kibana_sample_data_flights/_search
{
"explain": true,
"size": 5,
"query": {
"bool": {
"must": [
{
"match": {
"DestCountry": {
"query": "US",
"boost": 10
}
}
},
{
"term": {
"DestWeather": "Sunny"
}
}
],
"must_not": {
"term": {
"OriginCountry": "JP"
}
},
"filter": {
"range": {
"AvgTicketPrice": {
"lte": 1000
}
}
}
}
}
}

完整boosting语法,positive正向作用,negative负向作用,negative_boost负向作用的权重,可以用来降级匹配的文档,不像“NOT”逻辑运算直接去除相关的文档

GET movies/_search
{
//"explain": true,
"query": {
"boosting": {
"positive": {
"term": {
"title": {
"value": "beautiful"
}
}
},
"negative": {
"term": {
"title": {
"value": "mind"
}
}
},
"negative_boost": 0.2
}
}
}

constant_score 查询

尽管没有 bool 查询使用这么频繁,constant_score 查询也是我们工具箱里有用的查询工具。它将一个不变的常量评分应用于所有匹配的文档。它被经常用于你只需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下。

GET movies/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"title": "beautiful"
}
}
}
}
}

参考资料

Elasticsearch 复合查询——多字符串多字段查询的更多相关文章

  1. Hibernate 多表查询 - Criteria添加子字段查询条件 - 出错问题解决

    Criteria 查询条件如果是子对象中的非主键字段会报 could not resolve property private Criteria getCriteria(Favorite favori ...

  2. Elasticsearch+Mongo亿级别数据导入及查询实践

    数据方案: 在Elasticsearch中通过code及time字段查询对应doc的mongo_id字段获得mongodb中的主键_id 通过获得id再进入mongodb进行查询   1,数据情况: ...

  3. ElasticStack学习(十):深入ElasticSearch搜索之QueryFiltering、多/单字符串的多字段查询

    一.复合查询 1.在ElasticSearch中,有Query和Filter两种不同的Context.Query Context进行了相关性算分,Filter Context不需要进行算分,同时可以利 ...

  4. ElasticSearch 学习记录之ES查询添加排序字段和使用missing或existing字段查询

    ES添加排序 在默认的情况下,ES 是根据文档的得分score来进行文档额排序的.但是自己可以根据自己的针对一些字段进行排序.就像下面的查询脚本一样.下面的这个查询是根据productid这个值进行排 ...

  5. Mysql查询用逗号分隔的字段-字符串函数FIND_IN_SET(),以及此函数与in()函数的区别

    查询用逗号分隔的字段,可以用字符串函数FIND_IN_SET(): 查询数据库表中某个字段(值分行显示),可以用函数in(). 今天工作中遇到一个问题,就是用FIND_IN_SET()函数解决的. 第 ...

  6. Elasticsearch 单字符串多字段查询

    前言 有些时候,我们搜索的时候,只会提供一个输入框,但是会查询相关的多个字段,典型的如Google搜索,我们该如何用 Elasticsearch 如何实现呢? 实例 从单字符串查询的实例说起 创建测试 ...

  7. [Elasticsearch] 多字段搜索 (二) - 最佳字段查询及其调优

    最佳字段(Best Fields) 假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样: PUT /my_index/my_type/1 { "title": " ...

  8. [Elasticsearch] 多字段搜索 (二) - 最佳字段查询及其调优(转)

    最佳字段(Best Fields) 假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样: PUT /my_index/my_type/1 { "title": " ...

  9. ElasticSearch权威指南学习(结构化查询)

    请求体查询 简单查询语句(lite)是一种有效的命令行adhoc查询.但是,如果你想要善用搜索,你必须使用请求体查询(request body search)API. 空查询 我们以最简单的 sear ...

随机推荐

  1. UVA-10815 Andy's First Dictionary (非原创)

    10815 - Andy's First Dictionary Time limit: 3.000 seconds Problem B: Andy's First DictionaryTime lim ...

  2. 多线程(四) AQS底层原理分析

    J.U.C 简介 Java.util.concurrent 是在并发编程中比较常用的工具类,里面包含很多用来在并发 场景中使用的组件.比如线程池.阻塞队列.计时器.同步器.并发集合等等.并 发包的作者 ...

  3. 手工数据结构系列-C语言模拟队列和栈 hdu1702

    #include <stdio.h> #include <stdlib.h> //================= DATA STRUCTURE ============== ...

  4. ::-webkit-scrollbar & hidden scrollbar

    ::-webkit-scrollbar & hidden scrollbar how to hidden ::-webkit-scrollbar *::-webkit-scrollbar { ...

  5. React Testing All in One

    React Testing All in One React 测试 https://reactjs.org/docs/testing.html jest 26.4 https://jestjs.io/ ...

  6. Python 2 to Python 3 convert

    Python 2 to Python 3 convert 2to3, 自动将 Python 2 代码转为 Python 3 代码 https://docs.python.org/zh-cn/2/lib ...

  7. Kotlin & Android & Swift & Flutter & React Native

    Kotlin & Android https://www.runoob.com/kotlin/kotlin-tutorial.html Swift 5 & iOS 12 https:/ ...

  8. position: absolute; not work

    position: absolute; not work https://stackoverflow.com/questions/11928294/css-position-absolute-with ...

  9. NGK团队是如何打造超高回报率的BGV项目的?

    NGK旨在激励网络的供给端引导去中心化的节点集群,用于促进网络使用和增加带宽流动. 具体来讲,在未来的24个月内,NGK会将部分生态参与者纳入白名单系统有兴趣的参与者可关注官方信息. 对内,NGK采用 ...

  10. 离场定高转弯DF与CF的对比

    也许是刚学会CAD的缘故,配合风螺旋插件,画图的感觉真是蛮爽的,忍不住画了一张又一张. 接着昨天的离场保护区,我们来聊一下PBN指定高度转弯保护区的画法.指定高度转弯的计算本身没有太多复杂的地方,真正 ...