为了全面讲解 Elasticsearch 中的 document
,我们将从以下几个方面展开:
- 文档定义与特性
- 文档结构与字段
- 文档生命周期
- 文档 CRUD 操作
- 文档查询与过滤
- 文档关联与嵌套
- 文档分析与索引
- 文档版本控制与并发控制
1. 文档定义与特性
-
定义:在 Elasticsearch 中,
document
是数据的最小存储单元,相当于关系型数据库中的“行”。每个文档都有一个唯一的_id
,且内部由一系列键值对(field:value
)组成,采用 JSON 格式表示。 -
特性:
- 独立性:文档是独立的实体,无需与其他文档有明确的关系。
- 结构灵活:文档可以包含任意数量的字段,字段可以是简单类型(如字符串、数值、日期等)或复杂类型(如数组、嵌套对象等),且无需预定义严格的 schema。
- 动态映射:Elasticsearch 会根据文档首次索引时的实际内容自动推断字段类型和属性,实现动态映射。后期也可以通过显式定义映射(mapping)来约束字段类型和设置索引选项。
2. 文档结构与字段
-
结构:文档的 JSON 结构反映了数据的层次关系,可以包含嵌套的对象和数组。例如:
{ "user_id": "123", "username": "Alice", "email": "alice@example.com", "address": { "street": "123 Main St.", "city": "Anytown", "state": "CA", "zip": "12345" }, "tags": ["java", "python", "javascript"] }
-
字段:
- 字段类型:Elasticsearch 支持丰富的字段类型,如
text
(全文搜索)、keyword
(精确值)、integer
、float
、boolean
、date
、object
、nested
等。 - 字段属性:每个字段除了类型外,还可以设置各种属性,如是否存储(
store
)、是否索引(index
)、是否分析(analyzer
)、是否忽略空白字符(ignore_above
)等。
- 字段类型:Elasticsearch 支持丰富的字段类型,如
3. 文档生命周期
- 创建:通过
PUT
或POST
请求向索引添加文档。 - 更新:通过
UPDATE
或PUT
请求更新文档的部分或全部内容。更新实际上是先删除旧文档再创建新文档的过程,因此可能影响版本号和_source
字段。 - 检索:通过
GET
请求根据_id
查找文档,或通过SEARCH
请求根据查询条件检索文档。 - 删除:通过
DELETE
请求删除指定_id
的文档。 - ttl(可选):可以为文档设置生存时间(Time To Live),到期后自动删除。
4. 文档 CRUD 操作
-
创建(Create):
curl -X PUT "http://localhost:9200/users/user/1" -H 'Content-Type: application/json' -d' { "user_id": "1", "username": "Alice", "email": "alice@example.com" }'
-
读取(Read):
curl -X GET "http://localhost:9200/users/user/1?pretty"
-
更新(Update):
curl -X POST "http://localhost:9200/users/user/1/_update" -H 'Content-Type: application/json' -d' { "doc": { "email": "alice.new@example.com" } }'
-
删除(Delete):
curl -X DELETE "http://localhost:9200/users/user/1"
5. 文档查询与过滤
-
查询:使用
MATCH
、MULTI_MATCH
、TERM
、WILDCARD
、REGEXP
等查询语句进行全文搜索、精确匹配、通配符匹配、正则表达式匹配等。curl -X GET "http://localhost:9200/users/_search" -H 'Content-Type: application/json' -d' { "query": { "match": { "username": "Alice" } } }'
-
过滤:使用
TERM
、RANGE
、EXISTS
、MISSING
、TERMS
、BOOL
等过滤器进行精确值筛选、范围筛选、存在性判断、多值匹配、复合条件筛选等。curl -X GET "http://localhost:9200/users/_search" -H 'Content-Type: application/json' -d' { "query": { "bool": { "filter": [ { "term": { "status": "active" } }, { "range": { "age": { "gte": 18, "lte": 65 } } } ] } } }'
6. 文档关联与嵌套
-
嵌套对象:在文档中直接嵌套其他对象,便于表示一对多关系。查询时可以使用
nested
查询和聚合。{ "user_id": "1", "username": "Alice", "addresses": [ { "type": "home", "street": "123 Main St.", "city": "Anytown", "state": "CA", "zip": "12345" }, { "type": "work", "street": "456 Business Rd.", "city": "Othertown", "state": "NY", "zip": "67890" } ] }
-
父-子文档:通过
join
类型字段实现一对多关系,子文档与父文档共享相同的_id
前缀。查询时使用has_child
、has_parent
查询和聚合。// 父文档 { "_id": "user:1", "user_id": "1", "username": "Alice" } // 子文档 { "_id": "post:1", "_parent": "user:1", "post_id": "1", "title": "My First Blog Post", "content": "..." }
7. 文档分析与索引
-
分析:文档在索引之前会经过分析器(Analyzer)处理,将文本字段分解成词汇单元(tokens),并进行标准化、过滤、同义词扩展等操作。可以选择或自定义分析器以满足特定的搜索需求。
-
索引:分析后的词汇单元被存储到倒排索引中,用于快速定位包含特定词汇的文档。索引选项(如是否分词、是否存储原始值等)可以在映射中指定。
8. 文档版本控制与并发控制
-
版本控制:Elasticsearch 为每个文档维护一个版本号,每次对文档的修改都会递增版本号。在更新和删除操作中可以指定版本号,防止并发修改导致的数据丢失。
-
并发控制:使用乐观锁(Optimistic Concurrency Control,OCC)机制处理并发更新。客户端在更新文档时携带当前版本号,服务器端检查版本号是否与文档实际版本一致,一致则执行更新,否则返回
VersionConflictEngineException
。
通过以上内容,我们对 Elasticsearch 中的 document
进行了全面的讲解,涵盖了其定义、特性、结构、生命周期、CRUD 操作、查询与过滤、关联与嵌套、分析与索引,以及版本控制与并发控制等方面。这些知识是实战中进行数据管理、查询优化、索引设计等工作的基础。结合实际应用场景,深入理解并熟练运用这些概念和技术,将有助于充分发挥 Elasticsearch 的强大功能。