赞
踩
Elasticsearch中的查询条件和过滤条件都是用于搜索和过滤文档的条件,但它们之间有一些区别。
查询条件是用于计算文档相关度得分的条件,它会将所有符合条件的文档按照相关度得分从高到低排序,并返回前N个文档。查询条件可以使用各种类型的查询,如match、term、range、bool等。查询条件会计算每个文档的相关度得分,因此查询条件可以用于搜索和排序。
过滤条件是用于过滤文档的条件,它会将所有符合条件的文档返回,但不会计算相关度得分。过滤条件可以使用各种类型的过滤器,如term、range、bool、geo_distance等。过滤条件不会计算相关度得分,因此过滤条件可以用于过滤和聚合。
查询条件和过滤条件的区别在于,查询条件会计算每个文档的相关度得分,而过滤条件不会计算得分。因此,如果只需要过滤文档而不需要计算得分,应该使用过滤条件。另外,过滤条件可以缓存结果,提高查询性能,而查询条件不能缓存结果。
需要注意的是,查询条件和过滤条件都可以使用bool查询和bool过滤器来组合多个条件。bool查询和bool过滤器都是用于组合多个查询或过滤器的逻辑运算符,可以使用must、should、must_not三个子句来组合多个查询或过滤器。
ElasticSearch中的过滤器(Filter)是一种用于限制查询结果范围的查询类型,它可以根据指定的条件来过滤掉不符合要求的文档,从而提高查询效率。与查询(Query)不同,过滤器不会影响文档的相关性得分,而只是根据指定的条件来判断文档是否符合要求。
过滤器的作用和特性包括:
① 提高查询效率:过滤器可以在查询过程中快速过滤掉不符合要求的文档,从而减少查询的文档数量,提高查询效率。
② 不影响相关性得分:过滤器不会影响文档的相关性得分,因此可以与查询一起使用,同时满足查询条件和过滤条件。
③ 可以缓存:由于过滤器不会影响相关性得分,因此可以缓存过滤器的结果,以提高查询效率。
④ 支持多种条件:ElasticSearch提供了多种不同类型的过滤器,可以根据具体的查询需求选择不同的过滤器类型,如Term过滤器、Range过滤器、Bool过滤器等。
⑤ 可以组合使用:多个过滤器可以组合使用,使用逻辑运算符(如AND、OR、NOT)来定义它们之间的关系,从而实现更复杂的查询需求。
需要注意的是,过滤器虽然可以提高查询效率,但是也会占用一定的内存和CPU资源。因此,在使用过滤器时,需要根据具体的查询需求和系统资源情况进行权衡,选择合适的过滤器类型和参数。
在ElasticSearch中,过滤器(Filter)是一种用于限制查询结果范围的查询类型,它可以根据指定的条件来过滤掉不符合要求的文档,从而提高查询效率。ElasticSearch提供了多种不同类型的过滤器,包括:
① Term过滤器:用于精确匹配某个字段的值,类似于SQL中的等于(=)操作符。
② Range过滤器:用于匹配某个字段的值在指定范围内的文档,可以指定大于、小于、大于等于、小于等于等多种条件。
③ Exists过滤器:用于匹配某个字段存在的文档。
④ Bool过滤器:用于组合多个过滤器,可以使用逻辑运算符(如AND、OR、NOT)来定义它们之间的关系。
⑤ Type过滤器:用于匹配某个文档类型的文档。
⑥ Ids过滤器:用于匹配指定ID的文档。
⑦ Prefix过滤器:用于匹配某个字段以指定前缀开头的文档。
⑧ Wildcard过滤器:用于匹配某个字段符合指定通配符模式的文档。
⑨ Regexp过滤器:用于匹配某个字段符合指定正则表达式的文档。
以上是ElasticSearch中常用的一些过滤器类型,根据具体的查询需求,可以选择不同的过滤器来限制查询结果范围。
在ElasticSearch中,Term查询是一种精确匹配某个字段的值的查询类型,它不会计算文档的相关性得分(Relevance Score),因此不会影响查询结果的排序。
Term查询是一种非常快速和高效的查询类型,因为它只需要精确匹配某个字段的值,而不需要计算文档的相关性得分。因此,如果需要精确匹配某个字段的值,可以使用Term查询来提高查询效率。
需要注意的是,虽然Term查询不会计算文档的相关性得分,但是它仍然会返回所有匹配的文档,并按照相关性得分从高到低排序。这是因为,ElasticSearch中的查询结果总是会按照相关性得分从高到低排序,即使查询类型不会影响文档的相关性得分。
因此,虽然Term查询不会计算文档的相关性得分,但是它仍然会返回所有匹配的文档,并按照相关性得分从高到低排序。如果不需要排序,可以使用过滤器(Filter)来限制查询结果范围,以提高查询效率。
在ElasticSearch中,Bool查询可以组合多个查询条件和过滤条件,以实现更复杂的查询需求。当使用Bool查询时,查询结果会根据文档与查询条件的匹配程度计算相关性得分(Relevance Score),并按照相关性得分从高到低排序。
需要注意的是,虽然过滤器(Filter)不会影响文档的相关性得分,但是当过滤器与查询条件组合使用时,查询结果仍然会根据文档与查询条件的匹配程度计算相关性得分。这是因为,过滤器只是用来限制查询结果范围的,而查询条件则用来确定哪些文档匹配查询。因此,即使使用了过滤器,查询结果仍然需要根据文档与查询条件的匹配程度计算相关性得分。
在使用Bool查询时,如果只使用过滤器而不使用查询条件,那么查询结果不会有相关性得分,因为过滤器不会影响文档的相关性得分。但是,如果同时使用了查询条件和过滤器,那么查询结果仍然会有相关性得分,因为查询条件会影响文档的相关性得分。
因此,当使用Bool组合过滤器查询时,查询结果仍然会有相关性得分,这是因为查询条件的存在。如果不需要相关性得分,可以只使用过滤器来限制查询结果范围。
term查询:会将所有符合条件的文档按照相关度得分从高到低排序,并返回前N个文档。term查询只能精确匹配某个字段的值,不支持模糊匹配和范围查询。
term过滤器:通常用于不需要计算文档相关度得分的场景,例如精确匹配、范围查询、聚合等。term过滤器会将所有符合条件的文档返回,但不会计算相关度得分。term过滤器只能精确匹配某个字段的值,不支持模糊匹配和范围查询。
① 索引文档,构造数据:
PUT /my_index
{
"mappings": {
"properties": {
"price":{
"type": "integer"
}
}
}
}
PUT /my_index/_doc/1
{
"price":10
}
PUT /my_index/_doc/2
{
"price":20
}
PUT /my_index/_doc/3
{
"price":30
}
② 查询字段 price 值包含10的文档,并按照相关度得分从高到低排序:
GET /my_index/_search
{
"query": {
"term": {
"price": {
"value": 10
}
}
}
}
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"price" : 10
}
}
]
}
}
③ 查询字段 price 值包含10的文档,查询结果不会按照相关度得分排序:
GET /my_index/_search
{
"query": {
"bool": {
"filter": {
"term": {
"price": 10
}
}
}
}
}
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.0,
"_source" : {
"price" : 10
}
}
]
}
}
需要注意的是,term查询和term过滤器都是区分大小写的,因此如果字段值的大小写不一致,可能会导致查询结果不准确。另外,如果要查询或过滤的字段是一个text类型的字段,应该使用match查询或match_phrase查询,而不是term查询或term过滤器。因为text类型的字段会进行分词,term查询或term过滤器只能匹配整个词条,无法匹配分词后的单词。
terms查询:通常用于需要计算文档相关度得分的场景,例如全文搜索、排序等。terms查询会将所有符合条件的文档按照相关度得分从高到低排序,并返回前N个文档。terms查询可以匹配某个字段的值在指定值列表中。
terms过滤器:通常用于不需要计算文档相关度得分的场景,例如精确匹配、范围查询、聚合等。terms过滤器会将所有符合条件的文档返回,但不会计算相关度得分。terms过滤器可以匹配某个字段的值在指定值列表中。
① 索引文档,构造数据:
PUT /my_index
{
"mappings": {
"properties": {
"price":{
"type": "integer"
}
}
}
}
PUT /my_index/_doc/1
{
"price":10
}
PUT /my_index/_doc/2
{
"price":20
}
PUT /my_index/_doc/3
{
"price":30
}
② terms 查询:
GET /my_index/_search
{
"query": {
"terms": {
"price": [
"10",
"20"
]
}
}
}
{
"took" : 10,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"createTime" : "2023-03-29 10:30:11",
"tag" : "tag1",
"price" : 10
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"createTime" : "2023-03-29 10:35:11",
"tag" : "tag2",
"price" : 20
}
}
]
}
}
③ terms 过滤:
GET /my_index/_search
{
"query": {
"bool": {
"filter": {
"terms": {
"price": [
"10",
"20"
]
}
}
}
}
}
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.0,
"_source" : {
"createTime" : "2023-03-29 10:30:11",
"tag" : "tag1",
"price" : 10
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.0,
"_source" : {
"createTime" : "2023-03-29 10:35:11",
"tag" : "tag2",
"price" : 20
}
}
]
}
}
range查询:通常用于需要计算文档相关度得分的场景,例如全文搜索、排序等。range查询会将所有符合条件的文档按照相关度得分从高到低排序,并返回前N个文档。range查询可以匹配某个字段的值在指定范围内,支持数值、日期等类型的范围查询。
range过滤器:通常用于不需要计算文档相关度得分的场景,例如精确匹配、范围查询、聚合等。range过滤器会将所有符合条件的文档返回,但不会计算相关度得分。range过滤器可以匹配某个字段的值在指定范围内,支持数值、日期等类型的范围查询。
① 索引文档,构造数据:
PUT /my_index
{
"mappings": {
"properties": {
"price":{
"type": "integer"
}
}
}
}
PUT /my_index/_doc/1
{
"price":10
}
PUT /my_index/_doc/2
{
"price":20
}
PUT /my_index/_doc/3
{
"price":30
}
② 查询 price 字段的值在10到20之间的文档,并按照相关度得分从高到低排序:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"price" : 10
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"price" : 20
}
}
]
}
}
③ 查询 price 字段的值在10到20之间的文档,不按照相关度得分排序:
GET /my_index/_search
{
"query": {
"bool": {
"filter": {
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
}
}
}
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.0,
"_source" : {
"price" : 10
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.0,
"_source" : {
"price" : 20
}
}
]
}
}
需要注意的是,range查询和range过滤器的语法略有不同,但它们的功能是相同的。另外,range查询和range过滤器都可以用于数值、日期等类型的范围查询,但对于text类型的字段,应该使用match查询或match_phrase查询。
exists查询:通常用于需要计算文档相关度得分的场景,例如全文搜索、排序等。exists查询会将所有符合条件的文档按照相关度得分从高到低排序,并返回前N个文档。exists查询可以匹配某个字段不为空的文档。
exists过滤器:通常用于不需要计算文档相关度得分的场景,例如精确匹配、范围查询、聚合等。exists过滤器会将所有符合条件的文档返回,但不会计算相关度得分。exists查询可以匹配某个字段不为空的文档。
① 索引文档,构造数据:
PUT /my_index
{
"mappings": {
"properties": {
"price":{
"type": "integer"
}
}
}
}
PUT /my_index/_doc/1
{
"price":10
}
PUT /my_index/_doc/2
{
"price":20
}
PUT /my_index/_doc/3
{
"price":30
}
PUT /my_index/_doc/4
{
"price":null
}
② 查询 price 字段不为空的文档,并按照相关度得分从高到低排序:
GET /my_index/_search
{
"query": {
"exists": {
"field": "price"
}
}
}
{
"took" : 9,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"price" : 10
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"price" : 20
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"price" : 30
}
}
]
}
}
③ 查询 price 字段不为空的文档,不按照相关度得分排序:
GET /my_index/_search
{
"query": {
"bool": {
"filter": {
"exists": {
"field": "price"
}
}
}
}
}
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.0,
"_source" : {
"price" : 10
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.0,
"_source" : {
"price" : 20
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.0,
"_source" : {
"price" : 30
}
}
]
}
}
需要注意的是,exists查询和exists过滤器的语法略有不同,但它们的功能是相同的。对于text类型的字段,应该使用match查询或match_phrase查询。
ids查询:通常用于需要计算文档相关度得分的场景,例如全文搜索、排序等。ids查询会将所有符合条件的文档按照相关度得分从高到低排序,并返回前N个文档。ids查询可以匹配指定文档ID。
ids过滤器:通常用于不需要计算文档相关度得分的场景,例如精确匹配、范围查询、聚合等。ids过滤器会将所有符合条件的文档返回,但不会计算相关度得分。ids过滤器可以匹配指定文档ID。
① 索引文档,构造数据:
PUT /my_index
{
"mappings": {
"properties": {
"price":{
"type": "integer"
}
}
}
}
PUT /my_index/_doc/1
{
"price":10
}
PUT /my_index/_doc/2
{
"price":20
}
PUT /my_index/_doc/3
{
"price":30
}
② 查询 id=1或者 id=2的文档,并按照相关度得分从高到低排序:
GET /my_index/_search
{
"query": {
"ids": {
"values": [1,2]
}
}
}
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"price" : 10
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"price" : 20
}
}
]
}
}
③ 查询 id=1或者 id=2的文档,不按照相关度得分排序:
GET /my_index/_search
{
"query": {
"bool": {
"filter": {
"ids": {
"values": [
"1",
"2"
]
}
}
}
}
}
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.0,
"_source" : {
"price" : 10
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.0,
"_source" : {
"price" : 20
}
}
]
}
}
bool查询:通常用于需要计算文档相关度得分的场景,例如全文搜索、排序等。bool查询会将所有符合条件的文档按照相关度得分从高到低排序,并返回前N个文档。bool查询可以组合多个查询,支持must、should、must_not三个子句。
bool过滤器:通常用于不需要计算文档相关度得分的场景,例如精确匹配、范围查询、聚合等。bool过滤器会将所有符合条件的文档返回,但不会计算相关度得分。bool过滤器可以组合多个过滤器,支持must、should、must_not三个子句。
① 索引文档,构造数据:
PUT /my_index
{
"mappings": {
"properties": {
"createTime":{
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"tag":{
"type": "keyword"
},
"price":{
"type": "integer"
}
}
}
}
PUT /my_index/_doc/1
{
"createTime": "2023-03-29 10:30:11",
"tag": "tag1",
"price": 10
}
PUT /my_index/_doc/2
{
"createTime": "2023-03-29 10:35:11",
"tag": "tag2",
"price": 20
}
PUT /my_index/_doc/3
{
"createTime": "2023-03-29 10:38:11",
"tag": "tag3",
"price": 30
}
② bool 查询:
GET /my_index/_search
{
"query": {
"bool": {
"must_not": [
{
"term": {
"tag": {
"value": "tag1"
}
}
}
],
"should": [
{
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
],
"must": [
{
"term": {
"createTime": {
"value": "2023-03-29 10:38:11"
}
}
}
]
}
}
}
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"createTime" : "2023-03-29 10:38:11",
"tag" : "tag3",
"price" : 30
}
}
]
}
}
③ boo 过滤器:
GET /my_index/_search
{
"query": {
"bool": {
"filter": {
"bool": {
"must_not": [
{
"term": {
"tag": {
"value": "tag1"
}
}
}
],
"should": [
{
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
],
"must": [
{
"term": {
"createTime": {
"value": "2023-03-29 10:38:11"
}
}
}
]
}
}
}
}
}
{
"took" : 7,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.0,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.0,
"_source" : {
"createTime" : "2023-03-29 10:38:11",
"tag" : "tag3",
"price" : 30
}
}
]
}
}
GET /my_index/_search
{
"query": {
"bool": {
"filter": {
"bool": {
"must_not": [
{
"term": {
"tag": {
"value": "tag1"
}
}
}
],
"should": [
{
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
],
"must": [
{
"term": {
"createTime": {
"value": "2023-03-29 10:38:11"
}
}
}
]
}
}
}
}
}
@Slf4j
@Service
public class ElasticSearchImpl {
@Autowired
private RestHighLevelClient restHighLevelClient;
public void searchUser() throws IOException {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 内部 bool 过滤器
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
// must_not
TermQueryBuilder termQueryBuilder = new TermQueryBuilder("tag","tag1");
boolQueryBuilder.mustNot(termQueryBuilder);
// should
RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("price");
rangeQueryBuilder.gte(10);
rangeQueryBuilder.lte(20);
boolQueryBuilder.should(rangeQueryBuilder);
// must
termQueryBuilder = new TermQueryBuilder("createTime","2023-03-29 10:38:11");
boolQueryBuilder.must(termQueryBuilder);
// 外部 bool 过滤器
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
queryBuilder.filter(boolQueryBuilder);
searchSourceBuilder.query(queryBuilder);
SearchRequest searchRequest = new SearchRequest(new String[]{"my_index"},searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(searchResponse);
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。