【问题标题】:mongodb: create a top-level index for a nested document instead of having to index each individual sublevel?mongodb:为嵌套文档创建顶级索引,而不必索引每个单独的子级?
【发布时间】:2013-01-06 09:18:06
【问题描述】:

这个问题是关于如何使用 MongoDB 中的索引在嵌套文档中查找内容,而不必为每个单独的子级别编制索引。 我在 MongoDB 中有一个集合“测试”,基本上是这样的:

{
"_id" : ObjectId("50fdd7d71d41c82875a5b6c1"),
"othercol" : "bladiebla",
"scenario" : {
        "1" : { [1,2,3] },
        "2" : { [4,5,6] }
}}

场景有多个键,每个文档可以有场景的任何子集(即从无到子集到全部)。另外:场景不能是数组,因为我需要它作为 Python 中的字典。我在“场景”字段上创建了一个索引。
我的问题是我想在集合上进行选择,过滤具有一定价值的文档。所以这在功能上可以正常工作:

db.test.find({"scenario.1": {$exists: true}})

但是,它不会使用我在场景中设置的任何索引。只有当我在“scenario.1”上放置一个索引时,才会使用一个索引。但是我可以有数千个(或更多)场景(并且集合本身有 100.000 条记录),所以我不想这样做!
所以我尝试了替代方案:

db.test.find({"scenario": "1"}) 

这将在场景中使用索引,但不会返回结果。将场景设为数组仍然会出现相同的索引问题。

我的问题清楚了吗?谁能指点一下我如何在这里获得最佳性能?

附:我已经看到了这个:How to Create a nested index in MongoDB? 但在我的情况下这个解决方案是不可能的(由于场景的数量)

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    Johnny HK 的答案是一个很好解释的答案,应该在一般情况下使用。如果您必须有很多场景并且不需要复杂的查询,我只会为您建议一种解决方法来解决您的问题。不用将值保存在场景字段下,只需将场景的 id 保存在该字段下,并将值保存为文档中的另一个字段,并使用场景 id 作为该字段的键。

    例子:

    {
    "_id" : ObjectId("50fdd7d71d41c82875a5b6c1"),
    "othercol" : "bladiebla",
    "scenario" : [ "1", "2"],
    "scenario_1": [1,2,3],
    "scenario_2": [4,5,6]
    }}
    

    使用此架构,您可以使用场景索引来查找特定场景。但是如果您需要查询特定的场景值,您再次需要在每个场景值字段上都有一个索引,即场景_1、场景_2等。如果您需要为每个字段都有索引,那么不要更改您的原始架构和为每个嵌套字段使用稀疏索引,这可能有助于减少索引的大小。

    【讨论】:

    • 谢谢小熊!在我的特定用例中,我不需要过滤基础值,只需检索它们(在将文档写入 mongodb 之前,所有 null 和 0 值都已预先过滤)。我了解scenario_1解决方案的好处(使检索效率更高),但我的特定用例也需要比较,所以拥有这些数据实际上很好:)所以我要混合使用:我会添加您描述的场景数组+将保持嵌套字典在python中的原样。为了性能,名称有些冗余 :) 谢谢!
    【解决方案2】:

    在这种情况下,像 scenario 这样放置 index on a subobject 是没有用的,因为它只会在您过滤完整的 scenario 对象而不是单个字段时使用(将其视为二进制 blob 比较)。

    您需要在每个可能的字段("scenario.1""sceanario.2" 等)上添加索引,或者通过执行以下操作重新设计架构以摆脱动态键:

    {
    "_id" : ObjectId("50fdd7d71d41c82875a5b6c1"),
    "othercol" : "bladiebla",
    "scenario" : [
        { id: "1", value: [1,2,3] },
        { id: "2", value: [4,5,6] }
    }}
    

    然后您可以将单个索引添加到scenario.id 以支持您需要执行的查询。

    我知道你说过你需要 scenario 成为一个字典而不是一个数组,但我看不出你有多少选择。

    【讨论】:

    • 谢谢!真有见地!
    • (很遗憾我只能接受一个答案,但这个解释对我也很有帮助!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2013-07-27
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    相关资源
    最近更新 更多