https://www.elastic.co/guide/en/elasticsearch/reference/7.17/rest-apis.html
接口契约
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-search.html#search-search-api-example
以下bool查询单一must条件与term、match的效果一样。
但bool查询可以支持更多逻辑组合查询,比如must、should、must_not、filter等。
curl localhost:9200/_cat
curl localhost:9200/_cat/indices
curl localhost:9200/my_index/_search -H 'Content-Type: application/json' -d '{"query": {"term": {"id": 123}}}'
curl localhost:9200/my-index/_search?pretty&from=10&size=20
curl localhost:9200/my-index/_count
# -s参数:静默模式,隐藏curl进度信息;
# column -t:自动对齐列格式
# grep -E 'health|foo':保留标题行和含foo的索引
# v:显示列名标题行(verbose)
# pretty:格式化输出(可选)
curl -s $es/_cat/indices?v | column -t | grep -E 'health|foo'
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open index_foo abc 20 1 3406 2169 4.4mb 2.3mb
green open index_foo2 xyz 20 1 12583 12269 34.9mb 17.6mb
// 以下只列json条件,都需要header指定为json格式
{"query": {"term": {"name": "foo"}}}
{"query": {"match": {"name": "foo"}}}
// bool查询单一条件
{"query": {"bool": {
"must": [
{"match": {"name": "foo"}}
]
}}}
// bool查询多条件
{"query": {"bool": {
"must": [
{"match": {"id": 1}},
{"match": {"name": "foo"}}
]
}}}
{ "sort": [{"_id": {"order": "desc"}}], "query": {"match_all": {}} }
{"query": {"match": {"name": "foo"}}}
{"query": {"term": {"user.id": "foo" }}}
{"query": { "range": {"age": { "gte": 10, "lte": 20, "boost": 2.0 }}}}
# query.bool.must[term:{},range:{}] 复杂查询,嵌套结构深,不大好理解
{
"query": {
"bool": {
"must": [{
"term": {"foo_id": 123}
},
{
"range": { "update_time": { "gt": "2025-08-01T00:00:00+08:00", "lte": "2025-08-03T23:59:59+08:00" } }
}]
}
}
}
# 指定时区,据说Elasticsearch 默认使用UTC,不过估计以下time_zone也能识别
"update_time": {
"gt": "2025-08-01T00:00:00+08:00",
"lte": "2025-08-03T23:59:59+08:00",
"time_zone": "+08:00"
}
# 另一种写法,还没试过
{
"query": {
"bool": {
"filter": [ // 使用filter不计算相关性分数,提升性能
{ "term": { "foo_id": 123 }},
{ "range": { "update_time": { ... }}}
]
}
}
}
# 且条件,terms类似in的意思
{
"query": {
"bool": {
"must": [
{"term": { "FooName": "foo"}},
{"terms": {"Name": ["foo","bar"]}}
]
}
}
}
# 在旧索引上删除别名,同时在新索引上创建别名
curl -XPOST $es/_aliases -H 'Content-Type: application/json' -d '{"actions": [
{ "remove": { "index": "'foo'", "alias": "'f'" } },
{ "remove": { "index": "'bar'", "alias": "'b'" } },
{ "add": { "index": "'foov2'", "alias": "'f'" } },
{ "add": { "index": "'barv2'", "alias": "'b'" } }]}'
# 删除所有文档
curl -XPOST /foo/_delete_by_query?conflicts=proceed -H 'Content-Type: application/json' -d '{"query":{"match_all":{}}}'
# mapping为text时,发现es值既可以是字符串如"foo",也可以是字符串数组如["foo"]
"Name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
keyword类型、text类型,term查询、match查询使用的区别
注意:match查询条件中有空格、标点符号等分隔符才会按各分词进行查询,否则不会按分词查询,比如1 2 3因为有空格分析器将 "123" 分词成 "1", "2", "3"进行查找;而123就只会按123进行查询
user_id 为 keyword 类型,且值为123时,term和match两种查法有什么区别?
PUT /users {"mappings": {"properties": {"user_id": {"type": "keyword"}}}
PUT /users {"mappings": {"properties": {"user_id": {"type": "text"}}}
term 查询:精确匹配,适用于不分词的字段(如 keyword 类型)。它不会对查询词进行分析处理,因此适合用于查找特定值的场景,如查找特定ID的用户。
match 查询:模糊匹配或全文搜索,适用于分词的字段(如 text 类型),会对查询词进行分析处理。match 查询会将查询词分词,并尝试匹配文档中所有可能的词项。
Q:user_id 为 keyword 类型,且值为123时,term和match两种查法有什么区别?
user_id 为 keyword 类型时,使用match 查询也会查找 user_id 字段值为 "123" 的文档。尽管 match 查询通常用于全文搜索,并且会对查询词进行分析处理,但由于 user_id 是 keyword 类型,Elasticsearch 仍然不会对 "123" 进行分析处理。因此,match 查询在这种情况下也会直接匹配值为 "123" 的文档。
Q:user_id 为 text类型,且值为1 2 3时,term和match两种查法有什么区别?
如果值为
123没有空格就不会分词,两者返回结果是一样的
match 查询也会对 "1 2 3" 进行分析处理,并查找包含这些词项的文档。与 term 查询类似,如果分析器将 "123" 分词成 "1", "2", "3",那么 match 查询会查找包含这些词项的文档。但是,match 查询会根据词项的频率和文档长度等因素计算相关性得分,因此返回的结果可能会根据这些因素进行排序。
区别
匹配结果:两种查询方式都会因为 user_id 是 text 类型而导致意外的匹配结果。它们都会匹配包含 "1", "2", "3" 的文档,而不仅仅是值为 "1 2 3" 的文档。
相关性得分:match 查询会根据相关性得分对结果进行排序,而 term 查询不会。因此,match 查询的结果可能会根据词项的频率和文档长度等因素进行排序,而 term 查询的结果是根据文档的存储顺序返回的。
性能:term 查询通常比 match 查询更高效,因为 term 查询是为精确匹配设计的,而 match 查询的设计初衷是全文搜索,可能会涉及更多的内部处理逻辑。
结论
对于 text 类型的字段,使用 term 查询和 match 查询都会导致意外的匹配结果,因为它们都会对查询词进行分析处理。如果你需要精确匹配 user_id,应该将 user_id 映射为 keyword 类型,而不是 text 类型。这样可以确保 user_id 字段的值不会被分词,从而实现精确匹配。
多字段(multi-field)类型的term、match查询比较
如果user_id 字段被定义为一个多字段(multi-field)类型,其中包含两个子字段:一个是 text 类型,另一个是 keyword 类型。这种映射方式允许你在同一个字段上同时支持全文搜索和精确匹配。
# mapping
"user_id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
# term 查询:会精确匹配 user_id.keyword 字段值为 "123" 的文档。查询如下:
curl localhost:9200/users/_search -H 'Content-Type: application/json' -d '{"query": {"term": {"user_id.keyword": "123"}}}'
# match 查询:本例没有空格、标点符号等分隔符,将会按"123"整体来查询。查询如下:
# 如果条件为"1 2 3",因为有空格、标点符号等分隔符,就会查找包含 "1", "2", "3" 的文档,因为 user_id 是 text 类型,Elasticsearch 会对 "123" 进行分析处理。
curl localhost:9200/users/_search -H 'Content-Type: application/json' -d '{"query": {"match": {"user_id": "123"}}}'
本例中的多类型字段,如果条件中没有空格、标点符号等分隔符,term和match查询返回结果是一样的
多字段(Multi-Field)类型
1. 常见的类型和分析器
多字段(multi-field)类型允许你在同一个字段上支持多种查询需求。以下是一些常见的类型和分析器:
-
text类型:- 标准分析器(
standardanalyzer):默认的分析器,适用于大多数全文搜索场景。 -
lowercase分析器:将所有字符转换为小写,适用于需要忽略大小写的全文搜索。 -
whitespace分析器:按空格分词,适用于需要按空格分词的场景。 -
simple分析器:按非字母字符分词,适用于简单的全文搜索场景。 -
stop分析器:去除常见的停用词(如“the”, “is”等),适用于需要去除停用词的全文搜索场景。 - 自定义分析器:你可以定义自己的分析器,包括自定义的分词器、过滤器等,适用于特定的全文搜索需求。
- 标准分析器(
-
keyword类型:不进行分析处理,适用于需要精确匹配的场景,如用户ID、产品ID等。 -
date类型:支持多种日期格式,适用于日期时间字段。 -
integer、long、float、double类型:数值类型,支持范围查询、精确匹配等。 -
boolean类型:布尔值类型,支持精确匹配。
2. mappings示例
PUT /users
{
"mappings": {
"properties": {
"user_id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
},
"lowercase": {
"type": "text",
"analyzer": "lowercase"
},
"whitespace": {
"type": "text",
"analyzer": "whitespace"
},
"simple": {
"type": "text",
"analyzer": "simple"
},
"stop": {
"type": "text",
"analyzer": "stop"
}
}
},
"created_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis",
"fields": {
"keyword": {
"type": "keyword"
},
"lowercase": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
},
"whitespace": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
},
"simple": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
},
"stop": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
}
}
}
}
}
}
3. 数据示例
POST /users/_doc
{
"user_id": "123",
"created_at": "2023-10-01T12:00:00"
}
POST /users/_doc
{
"user_id": "134",
"created_at": "2023-10-02T13:00:00"
}
POST /users/_doc
{
"user_id": "135",
"created_at": "2023-10-03T14:00:00"
}
4. 查询示例
# 4.1 精确匹配
# 使用 term 查询查找 created_at.keyword 字段值为 "2023-10-01T12:00:00" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"term": {"created_at.keyword": "2023-10-01T12:00:00"}}'
# 4.2 范围查询
# 使用 range 查询查找 created_at 字段在 "2023-10-01" 和 "2023-10-03" 之间的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"range": {"created_at": {"gte": "2023-10-01", "lte": "2023-10-03"}}}'
# 4.3 忽略大小写的日期查询
# 使用 match 查询查找 created_at.lowercase 字段包含 "2023-10-01" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"match": {"created_at.lowercase": "2023-10-01"}}'
# 4.4 按空格分词的日期查询
# 使用 match 查询查找 created_at.whitespace 字段包含 "2023-10-01" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"match": {"created_at.whitespace": "2023-10-01"}}'
# 4.5 简单分词的日期查询
# 使用 match 查询查找 created_at.simple 字段包含 "2023-10-01" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"match": {"created_at.simple": "2023-10-01"}}'
# 4.6 去除停用词的日期查询
# 使用 match 查询查找 created_at.stop 字段包含 "2023-10-01" 的文档。
curl -X GET "http://localhost:9200/users/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"match": {"created_at.stop": "2023-10-01"}}'
5. 注意事项
- 日期格式:确保插入数据时的日期格式与映射中定义的格式一致。
- 时间戳:如果使用时间戳(如
epoch_millis),确保在查询时使用正确的时间戳格式。








网友评论