对于任何想要掌握 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中,索引是文档的集合,类似于关系型数据库中的"数据库"概念。每个索引包含一组具有相似特征的文档,并拥有独立的配置和映射。
核心特性:
索引的基本操作
创建索引:
json PUT /my_first_index { "settings": { "number_of_shards": 3, "number_of_replicas": 2, "refresh_interval": "1s" } }
查看索引信息:
json GET /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" } } } }
删除索引:
json DELETE /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)
手动定义所有字段类型,推荐生产环境使用:
json PUT /explicit_mapping_demo { "mappings": { "dynamic": "strict", // 禁止未定义的字段 "properties": { "title": { "type": "text", "analyzer": "standard" }, "views": { "type": "integer" } // 其他字段定义... } } }
dynamic 参数选项:
核心映射参数
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字段聚合,消耗大量内存 }
用于全文搜索的字符串:
json PUT /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
:自定义格式
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对象:
json PUT /object_demo { "mappings": { "properties": { "user": { "type": "object", "properties": { "name": {"type": "text"}, "age": {"type": "integer"} } } } } } // 插入文档 POST /object_demo/_doc { "user": { "name": "张三", "age": 30 } }
保持数组对象的独立性:
json PUT /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)
存储经纬度坐标:
json PUT /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 ] // 数组格式[经度,纬度] }
地理查询示例:
json GET /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 } }
多字段允许为同一内容以不同方式索引,实现不同搜索需求:
json PUT /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 } } } }
范围操作符:
对于日期字段,还支持相对时间:
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": "智能手机" } } }
搜索过程:
查找包含完整短语的文档,分词顺序必须完全匹配。
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 查询的四个子句:
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 } } }
这种查询在只需要过滤而不需要复杂评分时性能很好。
让我们结合所学知识,构建一个完整的电商商品搜索:
创建索引
json PUT /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" } } } }
初始化数据
json POST /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" }
请编写一个查询,满足以下条件:
json GET /products/_search { "query": { "bool": { "must": [ { "range": { "price": { "gte": 3000, "lte": 6000 } } }, { "terms": { "brand": [ "苹果", "三星" ] } } ] } }, "size": 10, "sort": [ { "price": { "order": "asc" } } ], "_source": [ "product_id", "name", "price" ] }
json GET /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);
通过本文,我们深入学习了:
关键要点:
思考题:尝试用今天学到的知识,构建一个搜索你业务场景的查询,比如博客文章搜索、用户搜索或日志搜索。
本文作者:张豪
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!