我有一个 128 GB 的数据集存储在 MongoDB 中。某些文档(最初是所有文档)缺少特定字段。该字段名为
flag_sent_to_kafka
。你可以猜猜它是做什么的。
因为我在决定将这些文档发送到 Kafka 之前创建了这些文档,所以整个数据集最初缺少此字段。
我可以编写一个过程来重新填充它,但我真的不想这样做,因为(我认为)它迫使我关闭生成文档的过程,直到更新整个数据集。这需要很长时间。
相反,创建一个索引似乎是一种更好的方法,该索引可用于查找具有字段
flag_sent_to_kafka
以及不具有字段 flag_sent_to_kafka
的文档。
我想出了这个 MongoSh 命令,但我不相信它是正确的。
db.search_results_data.createIndex(
{'flag_send_to_kafka': 1},
{'partialFilterExpression': { 'flag_send_to_kafka': {$exists: true} }}
)
文档页面显示了一些示例。这是一个这样的例子:
db.contacts.createIndex(
{ name: 1 },
{ partialFilterExpression: { email: { $exists: true } } }
)
第一个参数是
key
。在文档页面的示例中,密钥与 partialFilterExpression
中使用的密钥不匹配。 (name
vs email
)
这表明我编写的命令并没有按照我的想法进行。
这就是我想要实现的目标:
flag_sent_to_kafka
编辑:
创建此索引后,似乎并没有更快地找到文档。 (处理文件的速度没有增加。)
ChatGPT 表明我的情况是错误的。换句话说,它应该是
$exists: false
,以便快速查找没有此字段的文档。
但是,我尝试为此创建第二个索引,但没有成功:
db.search_results_data.createIndex(
{'flag_send_to_kafka': 1},
{'partialFilterExpression': { 'flag_send_to_kafka': {$exists: false} }}
)
Error in specification. [...] Expression not supported in partial index: $not
`flag_send_to_kafka` exists
为字段创建常规索引允许 MongoDB 索引所有具有该字段的文档,并通过差异间接索引那些不具有该字段的文档。这可以通过使用
$exists: false
运行查询来实现。
部分索引的预期目的通常是创建约束,而不是仅仅关注性能优化。一种常见的情况是,当您想要防止某些值对唯一存在时,但仅限于部分过滤器表达式定义的特定条件下。
例如,考虑以下情况,您希望禁止同一父级的两个子级具有相同的名称,但仅限于与部分过滤器表达式匹配的某些特殊情况。
db.tree.createIndex(
// prohibit two children of the same parent
{ parentId: 1, name: 1 },
// but only if they have (for example) the unique flag enabled
{ partialFilterExpression: { "uniqueFlag": true } }
)
因此,虽然常规索引涵盖所有文档,但当您想要根据特定条件对文档子集施加约束,确保索引仅包含满足这些条件的文档时,部分索引非常有用。