当前位置: 首页 > 知识库问答 >
问题:

对象嵌套数组的MongoDB查询优化

刘弘济
2023-03-14

我需要有关嵌套对象数组的查询优化的帮助。

我们有大量文档的集合,每个文档都包含嵌套的对象数组,最高可达3rd级,如下所示:

集合名称:产品

收集文件总数:2000万

每个文档的大小:

[
    {
        "_id":"ObjectId('121212')",
        "id":999,
        "name":"prod1",
        "sellers":[
            {
                "seller_id":99,
                "name":"Business 1",
                "providers":[
                    {
                        "seller_id":99,
                        "provider_id":1,
                        "provider_name":"prov 1",
                        "quantity":50,
                        "order_allowed":40,
                        "notification_on_stock":true
                    },
                    {
                        "seller_id":99,
                        "provider_id":2,
                        "provider_name":"prov 2",
                        "quantity":20,
                        "order_allowed":20,
                        "notification_on_stock":true
                    }
                ]
            },
            {
                "seller_id":9,
                "name":"Business 2",
                "providers":[
                    {
                        "seller_id":9,
                        "provider_id":3,
                        "provider_name":"prov 3",
                        "quantity":50,
                        "order_allowed":40,
                        "notification_on_stock":true
                    },
                    {
                        "seller_id":9,
                        "provider_id":4,
                        "provider_name":"prov 4",
                        "quantity":20,
                        "order_allowed":20,
                        "notification_on_stock":true
                    }
                ]
            }
        ]
    },
    {
        "_id":"ObjectId('232323')",
        "id":1000,
        "name":"prod 2",
        "sellers":[
            {
                "seller_id":44,
                "product_id":2,
                "name":"Business 22",
                "providers":[
                    {
                        "seller_id":44,
                        "provider_id":3,
                        "provider_name":"prov 3",
                        "quantity":50,
                        "order_allowed":40,
                        "notification_on_stock":true
                    },
                    {
                        "seller_id":44,
                        "provider_id":4,
                        "provider_name":"prov 4",
                        "quantity":20,
                        "order_allowed":20,
                        "notification_on_stock":true
                    }
                ]
            },
            {
                "seller_id":91,
                "name":"Business 21",
                "providers":[
                    {
                        "seller_id":91,
                        "provider_id":1,
                        "provider_name":"prov 1",
                        "quantity":50,
                        "order_allowed":40,
                        "notification_on_stock":true
                    },
                    {
                        "seller_id":91,
                        "provider_id":2,
                        "provider_name":"prov 2",
                        "quantity":20,
                        "order_allowed":20,
                        "notification_on_stock":true
                    }
                ]
            }
        ]
    },
    {
        "_id":"ObjectId('989798')",
        "id":1001,
        "name":"prod 3",
        "sellers":[
            {
                "seller_id":33,
                "name":"Business 112",
                "providers":[
                    {
                        "seller_id":33,
                        "provider_id":1,
                        "provider_name":"prov 1",
                        "quantity":50,
                        "order_allowed":40,
                        "notification_on_stock":true
                    },
                    {
                        "seller_id":33,
                        "provider_id":2,
                        "provider_name":"prov 2",
                        "quantity":20,
                        "order_allowed":20,
                        "notification_on_stock":true
                    }
                ]
            },
            {
                "seller_id":32,
                "name":"Business 2",
                "providers":[
                    {
                        "seller_id":32,
                        "provider_id":1,
                        "provider_name":"prov 1",
                        "quantity":50,
                        "order_allowed":40,
                        "notification_on_stock":true
                    },
                    {
                        "seller_id":32,
                        "provider_id":2,
                        "provider_name":"prov 2",
                        "quantity":20,
                        "order_allowed":20,
                        "notification_on_stock":true
                    }
                ]
            }
        ]
    }
]

我为我的产品集合添加了以下索引,如下所示:,

>

  • products.id索引

    { “id”:1 }

    嵌套数组文档的索引

    { " products . sellers . seller _ id ":1 }

    {
        "id":1,
        "sellers.seller_id":1,
        "sellers.providers.provider_id":1
    }
    

    我的疑问:

    db.products.find({
        "id":999,
        "sellers":{
            "$elemMatch":{
                "providers":{
                    "$elemMatch":{
                        "seller_id":30098,
                        "provider_id":517
                    }
                }
            }
        }
    });
    

    我的问题是查询总是在字段ID上拾取第一个索引,并且查询花费的时间约为800ms,我需要优化。

  • 共有1个答案

    邹英悟
    2023-03-14

    您的第三个复合指数将显示在剔除计划中,因为您的条件不同于您的复合指数,

    您在< code>provides中匹配< code>seller_id,但提供索引在< code>selles.seller_id中

    我不确定根据您的要求,什么是正确的,但请选择以下一项以实现获奖计划中的指标,

      < li >要么您的查询是错误的,您应该将其更改为以下内容,
    db.products.find({
        "id":999,
        "sellers":{
            "$elemMatch":{
                "seller_id":30098,
                "providers":{
                    "$elemMatch":{
                        "provider_id":517
                    }
                }
            }
        }
    });
    
    {
        "id":1,
        "sellers.providers.seller_id":1,
        "sellers.providers.provider_id":1
    }
    

    其次,我注意到你创建了错误的索引,我在你的文档中看不到任何产品键,

    嵌套数组文档的索引

    { " products . sellers . seller _ id ":1 }

     类似资料:
    • 问题内容: 我对mongodb还是很陌生,有一件事我现在无法解决: 假设您有以下文档(简体): 哪个查询将返回json-object,其值等于“ value2”? 这意味着,我需要这个json-object: 当然,我已经尝试了很多可能的查询,但是没有一个返回正确的查询,例如 有人可以帮我看看我在做什么错吗? 谢谢! 问题答案: 使用位置运算符 输出量 使用聚合 输出 使用Java驱动程序 输出

    • 我问了这个问题作为对另一个问题的评论,也在mongodb-user上发布了一个问题。到目前为止没有回复,所以我求助于问一个单独的问题。 文件说明: 如果字段包含一个数组,则$in操作符选择其字段包含数组的文档,该数组至少包含一个与指定数组中的值匹配的元素(例如,等等) 我正在使用: 在MongoDB外壳中: 下面是应根据文档及其生成的结果工作的查询列表: 为什么这个不行? 为什么我需要所有的钱?

    • 本文向大家介绍使用MongoDB查询特定嵌套文档的对象数组,包括了使用MongoDB查询特定嵌套文档的对象数组的使用技巧和注意事项,需要的朋友参考一下 要查询对象数组中的嵌套文档,请使用find()。让我们创建一个包含文档的集合- 在find()方法的帮助下显示集合中的所有文档- 这将产生以下输出- 以下是如何查询对象数组以获取特定的嵌套文档- 这将产生以下输出-

    • 问题内容: 我的JSON数据如下所示: 给定文本“ foo”,我想返回所有具有此子字符串的元组。但是我不知道如何编写相同的查询。 我遵循了这个相关的答案,但不知道该怎么做。 这是我现在正在工作的内容: 我不想传递整个文本,而是传递并获得与该文本匹配的结果。 问题答案: 您的解决方案可以进一步简化: 或更简单一点,因为在此示例中,您实际上根本不需要行类型(): dbfiddle 在这里 但这 不是

    • 我需要更新嵌套在我的用户文档中的一个字段,该字段包含一个part对象数组,以添加新的part。一个part对象如下所示: 所以这意味着$addToset对我的情况没有好处...现在我不知道该怎么办。

    • 在使用Mongoose查询数组时,我很难得到我期望看到的内容。一个用户可以有许多与他/她的帐户相关联的房间。room对象存储在集合中附加到用户的数组中。只有一个集合叫做Users。 请考虑以下user和Room的两个架构: 我还应该指出,数据库是填充的,因为我可以看到RoboMongo中的数组(在创建用户帐户时创建了1个元素)。 正在填充从控制台输出到show database的示例数据(包括us