为什么这个错误发生 #
document_source_missing_exception 表示文档存在但其源数据(_source)被禁用或丢失。这通常发生在尝试获取或更新文档的 _source 字段时。
这个错误可能由以下原因引起:
- _source 被禁用:索引映射中禁用了 _source
- _source 被过滤:_source 被exclude 配置过滤掉了
- 文档损坏:文档的 _source 数据损坏
- 更新操作冲突:在 _source 被禁用的索引上执行需要 _source 的操作
- 版本升级问题:从旧版本升级后 _source 数据丢失
如何修复这个错误 #
1. 检查索引映射 #
# 查看索引映射中的 _source 配置
GET /<index>/_mapping?pretty
# 检查 _source 是否被禁用
GET /<index>/_mapping?filter_path=**._source
2. 查看文档而不获取 _source #
# 使用 stored_fields 而不是 _source
GET /<index>/_doc/<id>?stored_fields=<field_name>
# 只返回文档元数据
GET /<index>/_doc/<id>?_source=false
3. 重新索引并启用 _source #
# 创建新索引并启用 _source
PUT /<index>-new
{
"mappings": {
"_source": {
"enabled": true
},
"properties": {
"field": { "type": "text" }
}
}
}
# 重新索引数据(注意:_source 丢失的数据无法恢复)
POST /_reindex
{
"source": { "index": "<index>" },
"dest": { "index": "<index>-new" }
}
4. 使用 doc 而不是 _source 更新 #
# 在禁用 _source 的索引上,使用 doc 更新
POST /<index>/_update/<id>
{
"doc": {
"field": "value"
}
}
# 或使用 upsert
POST /<index>/_update/<id>
{
"doc": {
"field": "value"
},
"doc_as_upsert": true
}
5. 检查 _source 过滤配置 #
# 检查是否配置了 exclude
GET /<index>/_mapping?filter_path=**._source
# 修改配置
PUT /<index>/_mapping
{
"_source": {
"excludes": []
}
}
6. 使用 stored fields #
# 在映射中配置存储字段
PUT /<index>
{
"mappings": {
"_source": { "enabled": false },
"properties": {
"title": {
"type": "text",
"store": true
}
}
}
}
# 检索存储的字段
GET /<index>/_doc/<id>?stored_fields=title
7. 验证文档是否存在 #
# 检查文档是否存在
HEAD /<index>/_doc/<id>
# 只获取元数据
GET /<index>/_doc/<id>?_source=false
8. 使用 script 进行更新 #
# 在某些情况下可以使用脚本更新
POST /<index>/_update/<id>
{
"script": {
"source": "ctx._source.field = params.value",
"lang": "painless"
},
"params": {
"value": "new_value"
}
}
# 注意:如果 _source 被禁用,这会失败
9. 从副本或备份恢复 #
# 如果有副本或备份
# 恢复启用了 _source 的数据
# 从快照恢复
POST /_snapshot/<repository>/<snapshot>/_restore
{
"indices": "<index>"
}
10. 修改映射(仅限新索引) #
# 注意:禁用 _source 后无法重新启用
# 需要创建新索引
PUT /<index>-v2
{
"mappings": {
"_source": {
"enabled": true,
"excludes": ["sensitive_field"]
}
}
}
预防措施 #
- 尽量不要禁用 _source(除非确定不需要)
- 如果要禁用 _source,考虑使用 store 存储关键字段
- 使用 excludes 而不是完全禁用 _source
- 在设计索引时仔细考虑 _source 配置
- 定期备份索引数据
- 在测试环境验证 _source 配置后再应用到生产





