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

问题描述

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

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

集合名称:产品

收集的文档总数:2000 万

每个文档的大小:>= 500 kb

[
    {
        "_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",{
                        "seller_id":9,"provider_id":4,"provider_name":"prov 4","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,{
                        "seller_id":44,{
                "seller_id":91,"name":"Business 21","providers":[
                    {
                        "seller_id":91,{
                        "seller_id":91,{
        "_id":"ObjectId('989798')","id":1001,"name":"prod 3","sellers":[
            {
                "seller_id":33,"name":"Business 112","providers":[
                    {
                        "seller_id":33,{
                        "seller_id":33,{
                "seller_id":32,"providers":[
                    {
                        "seller_id":32,{
                        "seller_id":32,"notification_on_stock":true
                    }
                ]
            }
        ]
    }
]

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

  1. products.id 上的索引

    { “身份证”:1 }

  2. 嵌套数组文档的索引

    { “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 上的第一个索引,查询花费了大约 800 毫秒的时间,我需要对其进行优化。

解决方法

您的第三个复合索引将显示在拒绝计划中,因为您的条件与您的复合索引不同,

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

我不确定您的要求是什么是正确的,但请选择以下一项以在获胜计划中获得指数,

  1. 要么您的查询有误,您应该将其更改为此,
db.products.find({
    "id":999,"sellers":{
        "$elemMatch":{
            "seller_id":30098,"providers":{
                "$elemMatch":{
                    "provider_id":517
                }
            }
        }
    }
});
  1. 或者你创建了错误的索引,你应该更正它,
{
    "id":1,"sellers.providers.seller_id":1,"sellers.providers.provider_id":1
}

第二次我注意到您创建了错误的索引,我在您的文档中看不到任何 products 键,

  1. 嵌套数组文档的索引

    { "products.sellers.seller_id":1 }