前言

有时我们在搜索电影的时候,包含了多个条件,比如主演是周星驰,打分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. Redis性能指标监控

    监控指标 •性能指标:Performance•内存指标: Memory•基本活动指标:Basic activity•持久性指标: Persistence•错误指标:Error 性能指标:Perform ...

  2. hive+postgres安装部署过程

    master节点安装元数据库,采用postgres:#useradd postgres#password postgressu - postgreswget https://ftp.postgresq ...

  3. hautoj 1268 小天使改名

    1268: 小天使改名 时间限制: 2 秒  内存限制: 128 MB提交: 437  解决: 123提交 状态 题目描述 小天使的b站帐号被大家发现啦.于是小天使决定改名,将他原有ID中的两个不同位 ...

  4. json-server All In One

    json-server All In One https://github.com/typicode/json-server#getting-started $ npm i -g json-serve ...

  5. Windows 10 自带 free 屏幕截图/录像软件 Game Bar! 不仅仅是game-游戏呦! 高清晰,高保真,perfect!不仅仅是游戏呦!

    good news! good news! good news! 重要的事情说三遍! Windows 10 自带  屏幕截图/录像软件 Game Bar! 以后再也不用第三方的 盗版软件了! 对于Wi ...

  6. vue 的 computed 属性在什么时间执行

    vue 的 computed 属性在什么时间执行

  7. SEO & JSON-LD & structured-data

    SEO & JSON-LD & structured-data script type="application/ld+json" script type=&quo ...

  8. Python module all in one

    Python module all in one Python Modules https://docs.python.org/3/tutorial/modules.html Fibonacc # F ...

  9. taro scroll tabs 滚动标签 切换

    taro scroll tabs 滚动标签 切换 https://www.cnblogs.com/lml-lml/p/10954069.html https://developers.weixin.q ...

  10. PM2 in depth

    PM2 in depth ecosystem.config.js module.exports = { apps : [{ name: "app", script: ". ...