Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在mongoDB中创建从两个集合读取的视图?_Mongodb_Aggregation Framework - Fatal编程技术网

如何在mongoDB中创建从两个集合读取的视图?

如何在mongoDB中创建从两个集合读取的视图?,mongodb,aggregation-framework,Mongodb,Aggregation Framework,从mongoDB语法开始,并在项目中使用。 我正在寻找一个解决方案,我可以结合两个以上的集合与夫妇的条件,以创建一个视图 这是我的收藏范围 /* 1 */ { "_id" : ObjectId("1"), "range" : { "start" : "00" }, "products" : [ { "id" : "01",

从mongoDB语法开始,并在项目中使用。 我正在寻找一个解决方案,我可以结合两个以上的集合与夫妇的条件,以创建一个视图

这是我的收藏范围

 /* 1 */
    {
        "_id" : ObjectId("1"),
        "range" : {
            "start" : "00" 
        },  
        "products" : [ 
            {
                "id" : "01",
                "name" : "FirstProduct",
                "type" : "First Type"
            }, 
            {
                "id" : "02",
                "name" : "Second Product",
                "type" : "Second Type"
            },
            {
                "id" : "03",
                "name" : "Third Product",
                "type" : "Third Type"
            },
        ]
    }

    /* 2 */
    {
        "_id" : ObjectId("2"),
        "range" : {
            "start" : "100",
        },  
        "products" : [ 
            {
                "id" : "01",
                "name" : "First Product",
                "type" : "First Type"
            }, 
            {
                "id" : "02",
                "name" : "Second Product",
                "type" : "Second Type"
            }
        ]
    }

   /* 3 */
    {
        "_id" : ObjectId("3"),
        "range" : {
            "start" : "500",
        },  
        "products" : [ 
            {
                "id" : "01",
                "name" : "First Product",
                "type" : "First Type"
            }, 
            {
                "id" : "02",
                "name" : "Second Product",
                "type" : "Second Type"
            }
        ]
    }
第二集股票

/* 1 */
{
    "_id" : ObjectId("1"),
    "range" : {
        "start" : "00"
    },
    "products" : [ 
        {
            "id" : "01",
            "expired" : false,
            "returned" : false
        }, 
        {
            "id" : "02",
            "expired" : false,
            "returned" : false
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("02"),
    "range" : {
        "start" : "100"
    },
    "products" : [ 
        {
            "id" : "01",
            "expired" : true,
            "returned" : true
        }, 
        {
            "id" : "02",
            "expired" : true,
            "returned" : true
        }
        {
            "id" : "03",
            "expired" : true,
            "returned" : true
        }
    ]
}
现在,我们想从上面两个集合中获得一个具有合并结果的视图

For each range document in Range collections

    if Range.range.start = Stock.range.start 

        if Range.products.id = Stock.products.id

          copy "expired" and "returned" field from Stock for that product and 
          add to Range.product

        end if  

    end if 

    Return Range
最后的结果如下

    /* 1 */
    {
        "_id" : ObjectId("1"),
        "range" : {
            "start" : "00" 
        },  
        "products" : [ 
            {
                "id" : "01",
                "name" : "FirstProduct",
                "type" : "First Type"
                "expired" : false,
                "returned" : false
            }, 
            {
                "id" : "02",
                "name" : "Second Product",
                "type" : "Second Type"
                "expired" : false,
                "returned" : false
            } 
        ]
    }

    /* 2 */
    {
        "_id" : ObjectId("2"),
        "range" : {
            "start" : "100",
        },  
        "products" : [ 
            {
                "id" : "01",
                "name" : "First Product",
                "type" : "First Type",
                "expired" : true,
                "returned" : true
            }, 
            {
                "id" : "02",
                "name" : "Second Product",
                "type" : "Second Type",
                "expired" : true,
                "returned" : true
            }
        ]
    }


   /* 3 */
    {
        "_id" : ObjectId("3"),
        "range" : {
            "start" : "500",
        },  
        "products" : [ 
            {
                "id" : "01",
                "name" : "First Product",
                "type" : "First Type"
            }, 
            {
                "id" : "02",
                "name" : "Second Product",
                "type" : "Second Type"
            }
        ]
    }
我从阶段开始,没有得到正确的查询。 如果有人能提供正确语法和正确聚合函数的帮助。 提前感谢。

您需要合并两个集合中的数据,但是您必须使用才能通过
product.id
匹配相应的文档。在最后一步中,您可以使用获取阵列:

db.Range.aggregate([
    {
        $lookup: {
            from: "Stock",
            localField: "range.start",
            foreignField: "range.start",
            as: "stock"
        }
    },
    {
        $unwind: "$stock"
    },
    {
        $unwind: "$products"
    },
    {
        $unwind: "$stock.products"
    },
    {
        $match: { $expr: { $eq: [ "$products.id", "$stock.products.id" ] } }
    },
    {
        $group: {
            _id: "$_id",
            "range": { $first: "$range" },
            products: {
                $push: {
                    id: "$products.id",
                    name: "$products.name",
                    type: "$products.type",
                    expired: "$stock.products.expired",
                    returned: "$stock.products.returned"
                }
            }
        }
    }
])
编辑:可选择的解决方案,它直接在阵列上使用和下面的命令进行操作。缺点是代码可读性较差,但好的方面是,当不存在匹配项时,它应该返回文档,并且使用这种方法可以获得更好的性能

db.Range.aggregate([
    {
        $lookup: {
            from: "Stock",
            localField: "range.start",
            foreignField: "range.start",
            as: "stock"
        }
    },
    {
        $unwind: "$stock"
    },
    {
        $addFields: {
            products: {
                $map: {
                    input: "$products",
                    as: "p",
                    in: {
                        $let: {
                            vars: {
                                stockItem: {
                                    $arrayElemAt: [
                                        { $filter: { input: "$stock.products", cond: { $eq: [ "$$p.id", "$$this.id" ] } } }, 0
                                    ]
                                }
                            },
                            in: {
                                $cond: [
                                    { $eq: [ "$$stockItem", undefined ] },
                                    "$$p",
                                    {
                                        id: "$$p.id",
                                        name: "$$p.name",
                                        type: "$$p.type",
                                        expired: "$$stockItem.expired",
                                        returned: "$$stockItem.returned",
                                    }
                                ]
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $project: {
            stock: 0
        }
    }
])

我从来没有使用过这个功能,所以我不确定它的成本效益,但它看起来像上面这样的管道可以用来创建一个
视图
,在这个视图上可以运行find()查询@Bajal是的,这可以作为管道参数传递,谢谢回复。是否可以从输入文档中获取所有字段值,而不是像“range”那样逐个获取它:{$first:“$range”}。正如示例中所示,只有字段存在,但实际问题中有许多字段存在。所以它将包含输入文档的所有字段+推送字段。@SanjayJain您可以先将$first用于所有字段。由于它们来自同一个文档(按_id分组),它们都将具有相同的值谢谢,而且产品条目仅在$eq:[“$products.id”,“$stock.products.id”]的情况下使用,但如果不匹配,则我需要不带out expire和return元素的产品条目。