ES查询之排序查询、分页查询、布尔查询

1|0一、Elasticsearch之排序查询

1|11. 准备数据

PUT test1/_doc/1 { "name":"顾老二", "age":30, "from": "gu", "desc": "皮肤黑、武器长、性格直", "tags": ["黑", "长", "直"] } PUT test1/_doc/2 { "name":"大娘子", "age":18, "from":"sheng", "desc":"肤白貌美,娇憨可爱", "tags":["白", "富","美"] } PUT test1/_doc/3 { "name":"龙套偏房", "age":22, "from":"gu", "desc":"mmp,没怎么看,不知道怎么形容", "tags":["造数据", "真","难"] } PUT test1/_doc/4 { "name":"石头", "age":29, "from":"gu", "desc":"粗中有细,狐假虎威", "tags":["粗", "大","猛"] } PUT test1/_doc/5 { "name":"魏行首", "age":25, "from":"广云台", "desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags":["闭月","羞花"] }

1|22. 排序查询:sort

1|02.1 降序:desc

  • 想到排序,出现在脑海中的无非就是升(正)序和降(倒)序。比如我们查询顾府都有哪些人,并根据age字段按照降序,并且,我只想看nmaeage字段:
GET test1/_doc/_search { "query": { "match": { "from": "gu" } }, "sort": [ { "age": { "order": "desc" } } ] }
  • 上例,在条件查询的基础上,我们又通过sort来做排序,根据age字段排序,是降序呢还是升序,由order字段控制,desc是降序。

  • 结果如下:

{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : null, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "1", "_score" : null, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] }, "sort" : [ 30 ] }, { "_index" : "test1", "_type" : "doc", "_id" : "4", "_score" : null, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] }, "sort" : [ 29 ] }, { "_index" : "test1", "_type" : "doc", "_id" : "3", "_score" : null, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] }, "sort" : [ 22 ] } ] } }
  • 上例中,结果是以降序排列方式返回的。

1|02.2 升序:asc

  • 那么想要升序怎么搞呢?
GET test1/_doc/_search { "query": { "match_all": {} }, "sort": [ { "age": { "order": "asc" } } ] }
  • 上例,想要以升序的方式排列,只需要将order值换为asc就可以了。

  • 结果如下:

{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 5, "max_score" : null, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "2", "_score" : null, "_source" : { "name" : "大娘子", "age" : 18, "from" : "sheng", "desc" : "肤白貌美,娇憨可爱", "tags" : [ "白", "富", "美" ] }, "sort" : [ 18 ] }, { "_index" : "test1", "_type" : "doc", "_id" : "3", "_score" : null, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] }, "sort" : [ 22 ] }, { "_index" : "test1", "_type" : "doc", "_id" : "5", "_score" : null, "_source" : { "name" : "魏行首", "age" : 25, "from" : "广云台", "desc" : "仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags" : [ "闭月", "羞花" ] }, "sort" : [ 25 ] }, { "_index" : "test1", "_type" : "doc", "_id" : "4", "_score" : null, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] }, "sort" : [ 29 ] }, { "_index" : "test1", "_type" : "doc", "_id" : "1", "_score" : null, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] }, "sort" : [ 30 ] } ] } }
  • 上例,可以看到结果是以age从小到大的顺序返回结果。

1|33. 不是什么数据类型都能排序

  • 那么,你可能会问,除了age,能不能以别的属性作为排序条件啊?来试试:
GET test1/chengyuan/_search { "query": { "match_all": {} }, "sort": [ { "name": { "order": "asc" } } ] }
  • 上例,我们以name属性来排序,来看结果:
{ "error": { "root_cause": [ { "type": "illegal_argument_exception", "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead." } ], "type": "search_phase_execution_exception", "reason": "all shards failed", "phase": "query", "grouped": true, "failed_shards": [ { "shard": 0, "index": "test1", "node": "wrtr435jSgi7_naKq2Y_zQ", "reason": { "type": "illegal_argument_exception", "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead." } } ], "caused_by": { "type": "illegal_argument_exception", "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.", "caused_by": { "type": "illegal_argument_exception", "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead." } } }, "status": 400 }
  • 结果跟我们想象的不一样,报错了!

  • 注意:在排序的过程中,只能使用可排序的属性进行排序,其他的都不行!那么可以排序的属性有哪些呢?

    • 数字

    • 日期

2|0二、Elasticsearch之分页查询

2|11. 准备数据

PUT test1/_doc/1 { "name":"顾老二", "age":30, "from": "gu", "desc": "皮肤黑、武器长、性格直", "tags": ["黑", "长", "直"] } PUT test1/_doc/2 { "name":"大娘子", "age":18, "from":"sheng", "desc":"肤白貌美,娇憨可爱", "tags":["白", "富","美"] } PUT test1/_doc/3 { "name":"龙套偏房", "age":22, "from":"gu", "desc":"mmp,没怎么看,不知道怎么形容", "tags":["造数据", "真","难"] } PUT test1/_doc/4 { "name":"石头", "age":29, "from":"gu", "desc":"粗中有细,狐假虎威", "tags":["粗", "大","猛"] } PUT test1/_doc/5 { "name":"魏行首", "age":25, "from":"广云台", "desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags":["闭月","羞花"] }

2|22. 分页查询:from/size

  • 我们来看看elasticsearch是怎么将结果分页的:
GET test1/_doc/_search { "query": { "match_all": {} }, "sort": [ { "age": { "order": "desc" } } ], "from": 2, "size": 1 }
  • 上例,首先以age降序排序,查询所有。并且在查询的时候,添加两个属性fromsize来控制查询结果集hits中的数据条数(只对hits内的结果条数有影响,后面要介绍的聚合函数的结果不在size和from的控制内)。

    • from参数定义了需要跳过的hits数,默认为0

    • size参数定义了需要返回的hits数目的最大值

  • 如上例的结果:

{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 5, "max_score" : null, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "5", "_score" : null, "_source" : { "name" : "魏行首", "age" : 25, "from" : "广云台", "desc" : "仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags" : [ "闭月", "羞花" ] }, "sort" : [ 25 ] } ] } }
  • 上例中,在返回的结果集中,从第2条开始,返回1条数据。

  • 那如果想要从第2条开始,返回2条结果怎么做呢?

GET test1/_doc/_search { "query": { "match_all": {} }, "sort": [ { "age": { "order": "desc" } } ], "from": 2, "size": 2 }
  • 上例中,我们指定from为2,意为从第2条开始返回,返回多少呢?size意为2条。

  • 还可以这样:

GET test1/_doc/_search { "query": { "match_all": {} }, "sort": [ { "age": { "order": "desc" } } ], "from": 4, "size": 2 }
  • 上例中,从第4条开始返回2条数据。

  • 结果如下:

{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 5, "max_score" : null, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "2", "_score" : null, "_source" : { "name" : "大娘子", "age" : 18, "from" : "sheng", "desc" : "肤白貌美,娇憨可爱", "tags" : [ "白", "富", "美" ] }, "sort" : [ 18 ] } ] } }
  • 上例中仅有一条数据,那是为啥呢?因为我们现在只有5条数据,从第4条开始查询,就只有1条符合条件,所以,就返回了1条数据。

  • 到这里,我们也可以看到,我们的查询条件越来越多,开始仅是简单查询,慢慢增加条件查询,增加排序,对返回结果进行限制。所以,我们可以说:对于elasticsearch来说,所有的条件都是可插拔的,彼此之间用,分割。比如说,我们在查询中,仅对返回结果进行限制:

GET test1/_doc/_search { "query": { "match_all": {} }, "from": 4, "size": 2 }
  • 上例中,在所有的返回结果中,结果从4开始返回2条数据。
{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 5, "max_score" : 1.0, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "3", "_score" : 1.0, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } } ] } }
  • 但我们只有1条符合条件的数据。

3|0三、Elasticsearch之布尔查询

3|11. 前言

  • 布尔查询是最常用的组合查询,用到了bool关键字。根据其内的子查询的规则,只有当文档满足所有子查询条件时,elasticsearch引擎才将结果返回。布尔查询支持的子查询条件共4种:

    • must(and)

    • should(or)

    • must_not(not)

    • filter

  • 下面我们来看看每个子查询条件都是怎么玩的。

3|22. 准备数据

PUT test1/_doc/1 { "name":"顾老二", "age":30, "from": "gu", "desc": "皮肤黑、武器长、性格直", "tags": ["黑", "长", "直"] } PUT test1/_doc/2 { "name":"大娘子", "age":18, "from":"sheng", "desc":"肤白貌美,娇憨可爱", "tags":["白", "富","美"] } PUT test1/_doc/3 { "name":"龙套偏房", "age":22, "from":"gu", "desc":"mmp,没怎么看,不知道怎么形容", "tags":["造数据", "真","难"] } PUT test1/_doc/4 { "name":"石头", "age":29, "from":"gu", "desc":"粗中有细,狐假虎威", "tags":["粗", "大","猛"] } PUT test1/_doc/5 { "name":"魏行首", "age":25, "from":"广云台", "desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags":["闭月","羞花"] }

3|33. must

  • 现在,我们用布尔查询所有from属性为gu的数据:
GET test1/_doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } } ] } } }
  • 上例中,我们通过在bool属性(字段)内使用must来作为查询条件,那么条件是什么呢?条件同样被match包围,就是fromgu的所有数据。

  • 这里需要注意的是must字段对应的是个列表,也就是说可以有多个并列的查询条件,一个文档满足各个子条件后才最终返回。

  • 结果如下:

{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 0.6931472, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "4", "_score" : 0.6931472, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "3", "_score" : 0.2876821, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } } ] } }
  • 上例中,可以看到,所有from属性为gu的数据查询出来了。

  • 那么,我们想要查询fromgu,并且age30的数据怎么搞呢?

GET test1/_doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } }, { "match": { "age": 30 } } ] } } }
  • 上例中,在must列表中,在增加一个age30的条件。

  • 结果如下:

{ "took" : 8, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.287682, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "1", "_score" : 1.287682, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } } ] } }
  • 上例,符合条件的数据被成功查询出来了。

  • 注意:现在你可能慢慢发现一个现象,所有属性值为列表的,都可以实现多个条件并列存在

3|44. should

  • 那么,如果想查询只要是fromgu或者tags闭月的数据怎么搞?
GET test1/_doc/_search { "query": { "bool": { "should": [ { "match": { "from": "gu" } }, { "match": { "tags": "闭月" } } ] } } }
  • 上例中,或关系的不能用must的了,而是要用should,只要符合其中一个条件就返回。

  • 结果如下:

{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 4, "max_score" : 0.6931472, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "4", "_score" : 0.6931472, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "5", "_score" : 0.5753642, "_source" : { "name" : "魏行首", "age" : 25, "from" : "广云台", "desc" : "仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags" : [ "闭月", "羞花" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "3", "_score" : 0.2876821, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } } ] } }
  • 返回了所有符合条件的结果。

3|55. must_not

  • 那么,如果我想要查询from既不是gu并且tags也不是可爱,还有age不是18的数据怎么办?
GET test1/_doc/_search { "query": { "bool": { "must_not": [ { "match": { "from": "gu" } }, { "match": { "tags": "可爱" } }, { "match": { "age": 18 } } ] } } }
  • 上例中,mustshould都不能使用,而是使用must_not,又在内增加了一个age18的条件。

结果如下:

{ "took" : 9, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.0, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "5", "_score" : 1.0, "_source" : { "name" : "魏行首", "age" : 25, "from" : "广云台", "desc" : "仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags" : [ "闭月", "羞花" ] } } ] } }
  • 上例中,只有魏行首这一条数据,因为只有魏行首既不是顾家的人,标签没有可爱那一项,年龄也不等于18
  • 这里有点需要补充,条件中age对应的18你写成整形还是字符串都没啥区别……

3|66. filter

  • 那么,如果要查询fromguage大于25的数据怎么查?
  • 范围查询用到了关键字 range ,其内部可以跟多个条件
GET test1/_doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } } ], "filter": { "range": { "age": { "gt": 25 } } } } } }
  • 这里就用到了filter条件过滤查询,过滤条件的范围用range表示,gt表示大于,大于多少呢?是25。

  • 结果如下:

{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 0.6931472, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "4", "_score" : 0.6931472, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } } ] } }
  • 上例中,age大于25的条件都已经筛选出来了。

  • 那么要查询fromguage大于等于30的数据呢?

GET test1/_doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } } ], "filter": { "range": { "age": { "gte": 30 } } } } } }
  • 上例中,大于等于用gte表示。

  • 结果如下:

{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.2876821, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } } ] } }
  • 那么,要查询age小于25的呢?
GET test1/_doc/_search { "query": { "bool": { "filter": { "range": { "age": { "lt": 25 } } } } } }
  • 上例中,小于用lt表示,结果如下:
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 0.0, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "2", "_score" : 0.0, "_source" : { "name" : "大娘子", "age" : 18, "from" : "sheng", "desc" : "肤白貌美,娇憨可爱", "tags" : [ "白", "富", "美" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "3", "_score" : 0.0, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } } ] } }
  • 在查询一个age小于等于18的怎么办呢?
GET test1/_doc/_search { "query": { "bool": { "filter": { "range": { "age": { "lte": 18 } } } } } }
  • 上例中,小于等于用lte表示。结果如下:
{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.0, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "2", "_score" : 0.0, "_source" : { "name" : "大娘子", "age" : 18, "from" : "sheng", "desc" : "肤白貌美,娇憨可爱", "tags" : [ "白", "富", "美" ] } } ] } }
  • 要查询fromguage25~30之间的怎么查?
GET test1/_doc/_search { "query": { "bool": { "must": [ { "match": { "from": "gu" } } ], "filter": { "range": { "age": { "gte": 25, "lte": 30 } } } } } }
  • 上例中,使用ltegte来限定范围。结果如下:
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 0.6931472, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "4", "_score" : 0.6931472, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } } ] } }
  • 那么,要查询fromshengage小于等于25的怎么查呢?其实结果,我们可能已经想到了,只有一条,因为只有盛家小六符合结果。
GET test1/_doc/_search { "query": { "bool": { "must": [ { "match": { "from": "sheng" } } ], "filter": { "range": { "age": { "lte": 25 } } } } } }
  • 结果果然不出洒家所料!
{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.6931472, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "2", "_score" : 0.6931472, "_source" : { "name" : "大娘子", "age" : 18, "from" : "sheng", "desc" : "肤白貌美,娇憨可爱", "tags" : [ "白", "富", "美" ] } } ] } }
  • 但是,洒家手一抖,将must换为should看看会发生什么?
GET test1/_doc/_search { "query": { "bool": { "should": [ { "match": { "from": "sheng" } } ], "filter": { "range": { "age": { "lte": 25 } } } } } }
  • 结果如下:
{ "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 0.6931472, "hits" : [ { "_index" : "test1", "_type" : "doc", "_id" : "2", "_score" : 0.6931472, "_source" : { "name" : "大娘子", "age" : 18, "from" : "sheng", "desc" : "肤白貌美,娇憨可爱", "tags" : [ "白", "富", "美" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "5", "_score" : 0.0, "_source" : { "name" : "魏行首", "age" : 25, "from" : "广云台", "desc" : "仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags" : [ "闭月", "羞花" ] } }, { "_index" : "test1", "_type" : "doc", "_id" : "3", "_score" : 0.0, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } } ] } }
  • 结果有点出乎意料,因为龙套偏房和魏行首不属于盛家,但也被查询出来了。那你要问了,怎么肥四?小老弟!这是因为在查询过程中,优先经过filter过滤,因为should是或关系,龙套偏房和魏行首的年龄符合了filter过滤条件,也就被放行了!所以,如果在filter过滤条件中使用should的话,结果可能不会尽如人意!建议使用must代替

  • 注意:filter工作于bool查询内。比如我们将刚才的查询条件改一下,把filterbool中挪出来。

GET test1/_doc/_search { "query": { "bool": { "must": [ { "match": { "from": "sheng" } } ] }, "filter": { "range": { "age": { "lte": 25 } } } } }
  • 如上例所示,我们将filterbool平级,看查询结果:
{ "error": { "root_cause": [ { "type": "parsing_exception", "reason": "[bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME]", "line": 12, "col": 5 } ], "type": "parsing_exception", "reason": "[bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME]", "line": 12, "col": 5 }, "status": 400 }
  • 结果报错了!所以,filter工作位置很重要。

3|77. 小结:

  • must:与关系,相当于关系型数据库中的and

  • should:或关系,相当于关系型数据库中的or

  • must_not:非关系,相当于关系型数据库中的not

  • filter:过滤条件。

  • range:条件筛选范围。

  • gt:大于,相当于关系型数据库中的>

  • gte:大于等于,相当于关系型数据库中的>=

  • lt:小于,相当于关系型数据库中的<

  • lte:小于等于,相当于关系型数据库中的<=


__EOF__

本文作者BigSun丶
本文链接https://www.cnblogs.com/Mcoming/p/18123627.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   BigSun丶  阅读(1843)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示