对于任何想要掌握 Elasticsearch 的开发者来说,Query DSL(Domain Specific Language)都是必须征服的核心领域。本文作为系列第一篇,将深入解析基础查询和复合查询,帮助你构建精准的搜索条件。
在开始具体查询之前,我们先理解什么是 Query DSL。
DSL(Domain Specific Language) 是专门针对特定领域的语言。Elasticsearch 的 Query DSL 是一个基于 JSON 的、丰富的查询语言,它允许你构建复杂的搜索条件,从简单的关键词匹配到复杂的多条件组合查询。
与传统的 SQL 相比,DSL 提供了更强大、更灵活的搜索能力:
sql-- SQL 方式
SELECT * FROM products
WHERE (name LIKE '%手机%' OR description LIKE '%手机%')
AND price BETWEEN 1000 AND 3000
AND category = 'electronics';
-- Elasticsearch DSL 方式(等价)
{
"query": {
"bool": {
"must": [
{ "match": { "name": "手机" } }
],
"should": [
{ "match": { "description": "手机" } }
],
"filter": [
{ "range": { "price": { "gte": 1000, "lte": 3000 } } },
{ "term": { "category": "electronics" } }
]
}
}
}
索引和映射是Elasticsearch数据建模的核心
在Elasticsearch中,索引是文档的集合,类似于关系型数据库中的"数据库"概念。每个索引包含一组具有相似特征的文档,并拥有独立的配置和映射。
核心特性:
分布式存储:索引数据分布在多个分片上
水平扩展:可通过增加分片实现容量扩展
独立配置:每个索引可独立设置映射、分片数、副本数等
索引的基本操作
创建索引:
jsonPUT /my_first_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2,
"refresh_interval": "1s"
}
}
查看索引信息:
jsonGET /my_first_index
// 返回结果示例
{
"my_first_index": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1627896531000",
"number_of_shards": "3",
"number_of_replicas": "2",
"uuid": "abc123...",
"version": {"created": "7100099"},
"provided_name": "my_first_index"
}
}
}
}
删除索引:
jsonDELETE /my_first_index
索引状态管理:
json// 关闭索引(不可写入和搜索,但数据保留)
POST /my_first_index/_close
// 打开索引
POST /my_first_index/_open
// 清空索引数据(保留索引结构)
POST /my_first_index/_delete_by_query
{
"query": {
"match_all": {}
}
}
映射是Elasticsearch中的模式定义,它定义了:
字段的数据类型
字段的索引方式
字段的分析器配置
字段的存储选项
动态映射(Dynamic Mapping)
Elasticsearch自动推断字段类型:
json// 创建索引,启用动态映射
PUT /dynamic_mapping_demo
{
"mappings": {
"dynamic": true // 默认值
}
}
// 插入文档,ES自动推断字段类型
POST /dynamic_mapping_demo/_doc
{
"title": "Elasticsearch Guide", // 推断为text
"views": 150, // 推断为long
"price": 29.99, // 推断为float
"published": true, // 推断为boolean
"publish_date": "2023-01-15", // 推断为date
"tags": ["search", "database"] // 推断为text[]
}
动态映射规则:
| JSON数据类型 | Elasticsearch数据类型 |
|---|---|
| string | text + keyword子字段 |
| integer | long |
| float | float |
| boolean | boolean |
| date | date |
| array | 根据第一个元素类型推断 |
| object | object |
显式映射(Explicit Mapping)
手动定义所有字段类型,推荐生产环境使用:
jsonPUT /explicit_mapping_demo
{
"mappings": {
"dynamic": "strict", // 禁止未定义的字段
"properties": {
"title": {
"type": "text",
"analyzer": "standard"
},
"views": {
"type": "integer"
}
// 其他字段定义...
}
}
}
dynamic 参数选项:
true:自动检测并添加新字段(默认)
false:忽略新字段(不索引但存储在_source)
strict:遇到未映射字段时拒绝文档(推荐)
核心映射参数
type - 字段数据类型:
json"title": {
"type": "text"
}
index - 控制字段是否被索引:
json"internal_id": {
"type": "keyword",
"index": false // 不索引,无法搜索但可聚合
}
store - 独立存储字段值:
json"content": {
"type": "text",
"store": true // 独立于_source存储
}
doc_values - 列式存储,用于排序和聚合:
json"price": {
"type": "float",
"doc_values": true // 默认开启
}
norms - 存储长度归一化因子,影响评分:
json"description": {
"type": "text",
"norms": false // 不需要评分时关闭,节省空间
}
null_value - 替换空值:
json"category": {
"type": "keyword",
"null_value": "unknown" // null替换为"unknown"
}
copy_to - 复制字段值到自定义_all字段:
json"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
}
// 搜索full_name字段可同时匹配first_name和last_name
文本字段专用参数
analyzer - 索引时分析器:
json"content": {
"type": "text",
"analyzer": "ik_max_word" // 中文细粒度分词
}
search_analyzer - 搜索时分析器:
json"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart" // 搜索时粗粒度分词
}
fielddata - 内存中字段数据(慎用):
json"tags": {
"type": "text",
"fielddata": true // 允许对text字段聚合,消耗大量内存
}
用于全文搜索的字符串:
jsonPUT /text_demo
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
用于精确值匹配:
json"status": {
"type": "keyword",
"ignore_above": 256, // 超过长度不索引
"normalizer": "lowercase" // 标准化处理
}
| 类型 | 范围 | 存储大小 | 使用场景 |
|---|---|---|---|
| long | -2⁶³ to 2⁶³-1 | 64-bit | 大整数计数 |
| integer | -2³¹ to 2³¹-1 | 32-bit | 一般整数 |
| short | -32,768 to 32,767 | 16-bit | 小范围数值 |
| byte | -128 to 127 | 8-bit | 状态码 |
| double | 64-bit双精度 | 64-bit | 科学计算 |
| float | 32-bit单精度 | 32-bit | 一般小数 |
| half_float | 16-bit半精度 | 16-bit | 节省空间 |
| scaled_float | 缩放浮点 | 可变 | 金融数据 |
json"metrics": {
"properties": {
"price": {
"type": "scaled_float",
"scaling_factor": 100 // 存储为整数,节省空间
},
"quantity": {
"type": "integer"
},
"rating": {
"type": "half_float"
}
}
}
json"timestamps": {
"properties": {
"create_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
},
"update_time": {
"type": "date",
"format": "strict_date_optional_time"
}
}
}
支持的日期格式:
epoch_millis:时间戳毫秒数
yyyy-MM-dd:基本日期格式
yyyy-MM-dd HH:mm
:自定义格式strict_date_optional_time:严格模式
json"flags": {
"properties": {
"is_published": {
"type": "boolean"
},
"is_deleted": {
"type": "boolean",
"null_value": false // null视为false
}
}
}
存储Base64编码的二进制数据:
json"attachment": {
"type": "binary",
"doc_values": false,
"store": true
}
处理JSON对象:
jsonPUT /object_demo
{
"mappings": {
"properties": {
"user": {
"type": "object",
"properties": {
"name": {"type": "text"},
"age": {"type": "integer"}
}
}
}
}
}
// 插入文档
POST /object_demo/_doc
{
"user": {
"name": "张三",
"age": 30
}
}
保持数组对象的独立性:
jsonPUT /nested_demo
{
"mappings": {
"properties": {
"products": {
"type": "nested",
"properties": {
"name": {"type": "keyword"},
"price": {"type": "float"}
}
}
}
}
}
// 嵌套查询示例
GET /nested_demo/_search
{
"query": {
"nested": {
"path": "products",
"query": {
"bool": {
"must": [
{"term": {"products.name": "手机"}},
{"range": {"products.price": {"gte": 1000}}}
]
}
}
}
}
}
Elasticsearch没有专门的数组类型,任何字段都可以包含多个值:
json"tags": {
"type": "keyword" // 可以存储单个值或多个值
}
// 插入数组数据
POST /array_demo/_doc
{
"tags": ["搜索", "数据库", "NoSQL"] // 自动处理为数组
}
地理点(Geo-point)
存储经纬度坐标:
jsonPUT /geo_demo
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
// 多种格式支持
POST /geo_demo/_doc
{
"location": {
"lat": 40.7128,
"lon": -74.0060
}
}
POST /geo_demo/_doc
{
"location": "40.7128,-74.0060" // 字符串格式
}
POST /geo_demo/_doc
{
"location": [ -74.0060, 40.7128 ] // 数组格式[经度,纬度]
}
地理查询示例:
jsonGET /geo_demo/_search
{
"query": {
"geo_distance": {
"distance": "10km",
"location": {
"lat": 40.7128,
"lon": -74.0060
}
}
}
}
地理形状(Geo-shape)
存储复杂地理形状:
json"boundary": {
"type": "geo_shape",
"strategy": "recursive"
}
// 插入多边形数据
POST /geo_shape_demo/_doc
{
"boundary": {
"type": "polygon",
"coordinates": [[
[100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
[100.0, 1.0], [100.0, 0.0]
]]
}
}
IP类型(IP)
存储IPv4和IPv6地址:
json"client_ip": {
"type": "ip"
}
// 范围查询示例
GET /logs/_search
{
"query": {
"range": {
"client_ip": {
"gte": "192.168.1.1",
"lte": "192.168.1.254"
}
}
}
}
完成建议类型(Completion)
用于自动完成功能:
json"suggest": {
"type": "completion",
"analyzer": "simple",
"preserve_separators": true,
"preserve_position_increments": true,
"max_input_length": 50
}
// 使用示例
POST /suggestion_demo/_doc
{
"suggest": {
"input": ["elasticsearch", "elastic"],
"weight": 10
}
}
令牌计数类型(Token count)
统计分词后的词条数量:
json"content": {
"type": "text",
"fields": {
"word_count": {
"type": "token_count",
"analyzer": "standard"
}
}
}
排名特征类型(Rank features)
用于学习排名(Learning to Rank):
json"features": {
"type": "rank_features"
}
// 插入数据
POST /ranking_demo/_doc
{
"features": {
"query_length": 10.5,
"pagerank": 8.2,
"url_length": 3.0
}
}
多字段允许为同一内容以不同方式索引,实现不同搜索需求:
jsonPUT /multi_field_demo
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word", // 主字段:中文分词
"fields": {
"keyword": {
"type": "keyword", // 子字段:精确匹配
"ignore_above": 256
},
"english": {
"type": "text", // 子字段:英文分词
"analyzer": "english"
},
"raw": {
"type": "text", // 子字段:不分词
"analyzer": "keyword"
}
}
}
}
}
}
不同搜索方式:
json// 使用主字段进行全文搜索
GET /multi_field_demo/_search
{
"query": {
"match": {
"title": "搜索引擎"
}
}
}
// 使用keyword字段进行精确匹配
GET /multi_field_demo/_search
{
"query": {
"term": {
"title.keyword": "Elasticsearch指南"
}
}
}
// 使用english字段进行英文搜索
GET /multi_field_demo/_search
{
"query": {
"match": {
"title.english": "search engine"
}
}
}
Elasticsearch 查询主要分为两大类:精准匹配(Term-level) 和 全文搜索(Full-text)。
精准匹配查询用于查找完全匹配指定值的文档,不进行分词分析。主要用于 keyword、date、integer 等确切值字段。
查找在指定字段中包含确切术语的文档。
json// 查找 category 字段精确等于 "electronics" 的商品
GET /products/_search
{
"query": {
"term": {
"category": {
"value": "electronics"
}
}
}
}
注意
对于 text 类型字段,使用 term 查询时需要小心。因为 text 字段会被分词,而 term 查询不会对搜索词进行分词。例如,搜索 "smart phone" 可能无法匹配到被分词为 ["smart", "phone"] 的文档。
查找指定字段匹配任意一个给定值的文档。
json// 查找 category 为 "electronics" 或 "books" 的商品
GET /products/_search
{
"query": {
"terms": {
"category": ["electronics", "books"]
}
}
}
查找指定字段在某个范围内的文档。
json// 查找价格在 1000 到 3000 之间,且上架时间在 2023年之后的商品
GET /products/_search
{
"query": {
"range": {
"price": {
"gte": 1000,
"lte": 3000
}
}
}
}
范围操作符:
gte:大于等于(≥)
gt:大于(>)
lte:小于等于(≤)
lt:小于(<)
对于日期字段,还支持相对时间:
json{
"range": {
"publish_date": {
"gte": "now-7d/d", // 7天前到现在
"lte": "now"
}
}
}
查找包含指定字段的文档(字段值不为 null 或空数组)。
json// 查找有描述信息的商品
GET /products/_search
{
"query": {
"exists": {
"field": "description"
}
}
}
查找指定字段以给定前缀开头的文档。
json// 查找名称以 "smart" 开头的商品
GET /products/_search
{
"query": {
"prefix": {
"name": "smart"
}
}
}
全文搜索查询用于在 text 字段上执行全文搜索,会考虑分词和相关性评分。
最常用的全文搜索查询,会对搜索词进行分词,然后查找包含任何分词结果的文档。
json// 搜索包含 "智能手机" 的商品
GET /products/_search
{
"query": {
"match": {
"description": "智能手机"
}
}
}
搜索过程:
搜索词 "智能手机" 被 IK 分词器分成:["智能", "手机"]
查找 description 字段包含 "智能" 或 "手机" 的文档
根据相关性评分(_score)对结果排序
查找包含完整短语的文档,分词顺序必须完全匹配。
json// 搜索包含完整短语 "智能手机" 的商品
GET /products/_search
{
"query": {
"match_phrase": {
"description": "智能手机"
}
}
}
slop 参数:允许短语间有一定间隔
json{
"query": {
"match_phrase": {
"description": {
"query": "智能 手机",
"slop": 2 // 允许词语间最多间隔2个词
}
}
}
}
在多个字段上执行相同的 match 查询。
json// 在 name 和 description 字段中搜索 "手机"
GET /products/_search
{
"query": {
"multi_match": {
"query": "手机",
"fields": ["name", "description"]
}
}
}
字段加权:
json{
"multi_match": {
"query": "手机",
"fields": ["name^3", "description"] // name字段的权重是description的3倍
}
}
复合查询允许你将多个查询组合起来,构建复杂的搜索逻辑。
bool 查询是最强大、最常用的复合查询,它允许你使用布尔逻辑组合多个查询。
bool 查询的四个子句:
must:必须匹配,贡献相关性评分(类似 AND)
should:应该匹配,贡献相关性评分(类似 OR)
must_not:必须不匹配,不贡献评分(类似 NOT)
filter:必须匹配,但不贡献相关性评分,性能更好
json// 复杂搜索示例:搜索电子产品中价格在2000-5000元之间的手机,优先显示有库存的
GET /products/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"category": "electronics"
}
},
{
"bool": {
"should": [
{ "match": { "name": "手机" } },
{ "match": { "description": "手机" } }
]
}
}
],
"filter": [
{
"range": {
"price": {
"gte": 2000,
"lte": 5000
}
}
}
],
"should": [
{
"term": {
"in_stock": true
}
}
],
"must_not": [
{
"term": {
"brand": "Unknown"
}
}
],
"minimum_should_match": 1 // 至少满足一个should条件
}
}
}
filter 与 must 的区别
理解这个区别对性能优化至关重要:
json// 使用 filter - 不计算评分,性能更好
{
"bool": {
"filter": [
{ "range": { "price": { "gte": 1000 } } },
{ "term": { "status": "active" } }
]
}
}
// 使用 must - 计算评分,性能稍差
{
"bool": {
"must": [
{ "range": { "price": { "gte": 1000 } } },
{ "term": { "status": "active" } }
]
}
}
最佳实践:对于不需要相关性评分的精确匹配条件(如范围、状态、标签等),优先使用 filter。
将查询包装起来,为所有匹配的文档赋予相同的恒定分数。
json// 所有匹配的文档都获得分数 1.0
GET /products/_search
{
"query": {
"constant_score": {
"filter": {
"term": { "category": "electronics" }
},
"boost": 1.0
}
}
}
这种查询在只需要过滤而不需要复杂评分时性能很好。
让我们结合所学知识,构建一个完整的电商商品搜索:
创建索引
jsonPUT /products
{
"mappings": {
"properties": {
"product_id": { "type": "keyword" },
"name": { "type": "text" },
"category": { "type": "keyword" },
"brand": { "type": "keyword" },
"color": { "type": "keyword" },
"memory": { "type": "keyword" },
"size": { "type": "keyword" },
"price": { "type": "float" },
"in_stock": { "type": "boolean" },
"created_at": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||epoch_millis" }
}
}
}
初始化数据
jsonPOST /products/_bulk
{ "index": { "_index": "products"} }
{ "product_id": "P001", "name": "苹果 iPhone 15 Pro Max 银色 256GB", "category": "智能手机", "brand": "苹果", "color": "银色", "memory": "256GB", "size": "6.7英寸", "price": 9999, "in_stock": true, "created_at": "2025-11-01 10:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P002", "name": "三星 Galaxy S23 Ultra 蓝色 512GB", "category": "智能手机", "brand": "三星", "color": "蓝色", "memory": "512GB", "size": "6.8英寸", "price": 8999, "in_stock": false, "created_at": "2025-11-02 11:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P003", "name": "小米 Mi 13 Pro 黑色 1TB", "category": "智能手机", "brand": "小米", "color": "黑色", "memory": "1TB", "size": "6.78英寸", "price": 4999, "in_stock": true, "created_at": "2025-11-03 12:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P004", "name": "华为 Mate 60 Pro 白色 256GB", "category": "智能手机", "brand": "华为", "color": "白色", "memory": "256GB", "size": "6.74英寸", "price": 6999, "in_stock": true, "created_at": "2025-11-04 13:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P005", "name": "OPPO Find X6 Pro 紫色 512GB", "category": "智能手机", "brand": "OPPO", "color": "紫色", "memory": "512GB", "size": "6.82英寸", "price": 5999, "in_stock": true, "created_at": "2025-11-05 14:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P006", "name": "vivo X90 Pro+ 黑色 1TB", "category": "智能手机", "brand": "vivo", "color": "黑色", "memory": "1TB", "size": "6.78英寸", "price": 4999, "in_stock": true, "created_at": "2025-11-06 15:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P007", "name": "荣耀 Magic5 Pro 银色 512GB", "category": "智能手机", "brand": "荣耀", "color": "银色", "memory": "512GB", "size": "6.81英寸", "price": 5999, "in_stock": true, "created_at": "2025-11-07 16:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P008", "name": "一加 Ace Pro 深空灰 256GB", "category": "智能手机", "brand": "一加", "color": "深空灰", "memory": "256GB", "size": "6.7英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-08 17:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P009", "name": "realme GT Neo 5 SE 绿色 128GB", "category": "智能手机", "brand": "realme", "color": "绿色", "memory": "128GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-09 18:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P010", "name": "魅族 20 Pro 黑色 512GB", "category": "智能手机", "brand": "魅族", "color": "黑色", "memory": "512GB", "size": "6.8英寸", "price": 4999, "in_stock": true, "created_at": "2025-11-10 19:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P011", "name": "中兴 Axon 50 Ultra 蓝色 512GB", "category": "智能手机", "brand": "中兴", "color": "蓝色", "memory": "512GB", "size": "6.8英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-11 20:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P012", "name": "联想 Moto Edge 30 Ultra 黑色 512GB", "category": "智能手机", "brand": "联想", "color": "黑色", "memory": "512GB", "size": "6.8英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-12 21:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P013", "name": "诺基亚 G21 Plus 黄色 128GB", "category": "智能手机", "brand": "诺基亚", "color": "黄色", "memory": "128GB", "size": "6.55英寸", "price": 1999, "in_stock": true, "created_at": "2025-11-13 22:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P014", "name": "zte Axon 40 Ultra 黑色 512GB", "category": "智能手机", "brand": "zte", "color": "黑色", "memory": "512GB", "size": "6.8英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-14 23:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P015", "name": "荣耀 Play 7T 黑色 128GB", "category": "智能手机", "brand": "荣耀", "color": "黑色", "memory": "128GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-15 00:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P016", "name": "小米 Redmi Note 13 Pro 黑色 256GB", "category": "智能手机", "brand": "小米", "color": "黑色", "memory": "256GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-16 01:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P017", "name": "三星 Galaxy A54 金色 128GB", "category": "智能手机", "brand": "三星", "color": "金色", "memory": "128GB", "size": "6.4英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-17 02:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P018", "name": "苹果 iPhone 14 Pro 极夜黑 128GB", "category": "智能手机", "brand": "苹果", "color": "极夜黑", "memory": "128GB", "size": "6.1英寸", "price": 7999, "in_stock": true, "created_at": "2025-11-01 03:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P019", "name": "华为 P60 Pro 浅蓝 256GB", "category": "智能手机", "brand": "华为", "color": "浅蓝", "memory": "256GB", "size": "6.67英寸", "price": 5999, "in_stock": true, "created_at": "2025-11-02 04:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P020", "name": "OPPO Reno10 Pro+ 宇宙黑 512GB", "category": "智能手机", "brand": "OPPO", "color": "宇宙黑", "memory": "512GB", "size": "6.8英寸", "price": 4999, "in_stock": true, "created_at": "2025-11-03 05:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P021", "name": "vivo Y77t 天青色 128GB", "category": "智能手机", "brand": "vivo", "color": "天青色", "memory": "128GB", "size": "6.67英寸", "price": 1999, "in_stock": true, "created_at": "2025-11-04 06:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P022", "name": "荣耀 V40 Pro 暗影黑 256GB", "category": "智能手机", "brand": "荣耀", "color": "暗影黑", "memory": "256GB", "size": "6.76英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-05 07:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P023", "name": "一加 Ace 2V 玫瑰金 128GB", "category": "智能手机", "brand": "一加", "color": "玫瑰金", "memory": "128GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-06 08:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P024", "name": "realme GT Neo 5 黑色 256GB", "category": "智能手机", "brand": "realme", "color": "黑色", "memory": "256GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-07 09:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P025", "name": "魅族 20 黑色 128GB", "category": "智能手机", "brand": "魅族", "color": "黑色", "memory": "128GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-08 10:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P026", "name": "中兴 Axon 30 Ultra 紫色 256GB", "category": "智能手机", "brand": "中兴", "color": "紫色", "memory": "256GB", "size": "6.8英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-09 11:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P027", "name": "联想 Moto G73 Turbo 黑色 128GB", "category": "智能手机", "brand": "联想", "color": "黑色", "memory": "128GB", "size": "6.8英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-10 12:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P028", "name": "诺基亚 G21 Plus 银色 128GB", "category": "智能手机", "brand": "诺基亚", "color": "银色", "memory": "128GB", "size": "6.55英寸", "price": 1999, "in_stock": true, "created_at": "2025-11-11 13:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P029", "name": "zte Axon 30 Ultra 蓝色 256GB", "category": "智能手机", "brand": "zte", "color": "蓝色", "memory": "256GB", "size": "6.8英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-12 14:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P030", "name": "荣耀 Play 7T 黑色 128GB", "category": "智能手机", "brand": "荣耀", "color": "黑色", "memory": "128GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-13 15:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P031", "name": "小米 Redmi Note 13 Pro 黑色 256GB", "category": "智能手机", "brand": "小米", "color": "黑色", "memory": "256GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-14 16:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P032", "name": "三星 Galaxy A54 金色 128GB", "category": "智能手机", "brand": "三星", "color": "金色", "memory": "128GB", "size": "6.4英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-15 17:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P033", "name": "苹果 iPhone 14 Pro 极夜黑 128GB", "category": "智能手机", "brand": "苹果", "color": "极夜黑", "memory": "128GB", "size": "6.1英寸", "price": 7999, "in_stock": true, "created_at": "2025-11-16 18:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P034", "name": "华为 P60 Pro 浅蓝 256GB", "category": "智能手机", "brand": "华为", "color": "浅蓝", "memory": "256GB", "size": "6.67英寸", "price": 5999, "in_stock": true, "created_at": "2025-11-17 19:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P035", "name": "OPPO Reno10 Pro+ 宇宙黑 512GB", "category": "智能手机", "brand": "OPPO", "color": "宇宙黑", "memory": "512GB", "size": "6.8英寸", "price": 4999, "in_stock": true, "created_at": "2025-11-01 20:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P036", "name": "vivo Y77t 天青色 128GB", "category": "智能手机", "brand": "vivo", "color": "天青色", "memory": "128GB", "size": "6.67英寸", "price": 1999, "in_stock": true, "created_at": "2025-11-02 21:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P037", "name": "荣耀 V40 Pro 暗影黑 256GB", "category": "智能手机", "brand": "荣耀", "color": "暗影黑", "memory": "256GB", "size": "6.76英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-03 22:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P038", "name": "一加 Ace 2V 玫瑰金 128GB", "category": "智能手机", "brand": "一加", "color": "玫瑰金", "memory": "128GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-04 23:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P039", "name": "realme GT Neo 5 黑色 256GB", "category": "智能手机", "brand": "realme", "color": "黑色", "memory": "256GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-05 00:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P040", "name": "魅族 20 黑色 128GB", "category": "智能手机", "brand": "魅族", "color": "黑色", "memory": "128GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-06 01:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P041", "name": "中兴 Axon 30 Ultra 紫色 256GB", "category": "智能手机", "brand": "中兴", "color": "紫色", "memory": "256GB", "size": "6.8英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-07 02:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P042", "name": "联想 Moto G73 Turbo 黑色 128GB", "category": "智能手机", "brand": "联想", "color": "黑色", "memory": "128GB", "size": "6.8英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-08 03:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P043", "name": "诺基亚 G21 Plus 银色 128GB", "category": "智能手机", "brand": "诺基亚", "color": "银色", "memory": "128GB", "size": "6.55英寸", "price": 1999, "in_stock": true, "created_at": "2025-11-09 04:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P044", "name": "zte Axon 30 Ultra 蓝色 256GB", "category": "智能手机", "brand": "zte", "color": "蓝色", "memory": "256GB", "size": "6.8英寸", "price": 3999, "in_stock": true, "created_at": "2025-11-10 05:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P045", "name": "荣耀 Play 7T 黑色 128GB", "category": "智能手机", "brand": "荣耀", "color": "黑色", "memory": "128GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-11 06:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P046", "name": "小米 Redmi Note 13 Pro 黑色 256GB", "category": "智能手机", "brand": "小米", "color": "黑色", "memory": "256GB", "size": "6.7英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-12 07:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P047", "name": "三星 Galaxy A54 金色 128GB", "category": "智能手机", "brand": "三星", "color": "金色", "memory": "128GB", "size": "6.4英寸", "price": 2999, "in_stock": true, "created_at": "2025-11-13 08:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P048", "name": "苹果 iPhone 14 Pro 极夜黑 128GB", "category": "智能手机", "brand": "苹果", "color": "极夜黑", "memory": "128GB", "size": "6.1英寸", "price": 7999, "in_stock": true, "created_at": "2025-11-14 09:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P049", "name": "华为 P60 Pro 浅蓝 256GB", "category": "智能手机", "brand": "华为", "color": "浅蓝", "memory": "256GB", "size": "6.67英寸", "price": 5999, "in_stock": true, "created_at": "2025-11-15 10:00:00" }
{ "index": { "_index": "products"} }
{ "product_id": "P050", "name": "OPPO Reno10 Pro+ 宇宙黑 512GB", "category": "智能手机", "brand": "OPPO", "color": "宇宙黑", "memory": "512GB", "size": "6.8英寸", "price": 4999, "in_stock": true, "created_at": "2025-11-16 11:00:00" }
请编写一个查询,满足以下条件:
jsonGET /products/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"price": {
"gte": 3000,
"lte": 6000
}
}
},
{
"terms": {
"brand": [
"苹果",
"三星"
]
}
}
]
}
},
"size": 10,
"sort": [
{
"price": {
"order": "asc"
}
}
],
"_source": [
"product_id", "name", "price"
]
}
jsonGET /products/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"in_stock": {
"value": true
}
}
}
],
"filter": [
{
"terms": {
"color": [
"黑色",
"白色"
]
}
}
]
}
},
"size": 5,
"sort": [
{
"created_at": {
"order": "desc"
}
}
],
"_source": [
"product_id","name","created_at"
]
}
作为 Java 开发者,你可能更关心如何在代码中构建这些查询:
java// 使用 Java High Level REST Client
SearchRequest searchRequest = new SearchRequest("products");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 构建 bool 查询
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.multiMatchQuery("无线蓝牙耳机", "name", "description")
.operator(Operator.AND))
.filter(QueryBuilders.rangeQuery("price").gte(100).lte(1000))
.filter(QueryBuilders.termsQuery("brand", "Sony", "Bose", "Sennheiser"))
.should(QueryBuilders.termQuery("is_featured", true).boost(2))
.mustNot(QueryBuilders.termQuery("status", "discontinued"))
.minimumShouldMatch(1);
sourceBuilder.query(boolQuery);
sourceBuilder.from(0);
sourceBuilder.size(20);
sourceBuilder.sort("_score", SortOrder.DESC);
sourceBuilder.sort("created_at", SortOrder.DESC);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
通过本文,我们深入学习了:
精准匹配查询:term, terms, range, exists 等,用于精确值查找
全文搜索查询:match, match_phrase, multi_match 等,用于文本内容搜索
复合查询:主要是 bool 查询,用于构建复杂的搜索逻辑
关键要点:
理解字段类型:text 字段适合全文搜索,keyword 字段适合精准匹配
善用 filter 上下文:对于不关心评分的精确匹配,使用 filter 提升性能
合理使用 bool 查询:它是构建复杂搜索需求的瑞士军刀
注意评分影响:must 和 should 影响评分,filter 和 must_not 不影响
思考题:尝试用今天学到的知识,构建一个搜索你业务场景的查询,比如博客文章搜索、用户搜索或日志搜索。
本文作者:柳始恭
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!