Mongodb 如何使$lookup直接嵌入文档而不是将其包装到数组中?

Mongodb 如何使$lookup直接嵌入文档而不是将其包装到数组中?,mongodb,Mongodb,我有这样一份文件: { "_id": ObjectId("5d779541bd4e75c58d598212") "client": ObjectId("5d779558bd4e75c58d598213") } { from: 'client', localField: 'client', foreignField: 'id', as: 'client', } 当我这样做$lookup时: { "_id": ObjectId("5d779

我有这样一份文件:

{
    "_id": ObjectId("5d779541bd4e75c58d598212")
    "client": ObjectId("5d779558bd4e75c58d598213")
}
{
    from: 'client',
    localField: 'client',
    foreignField: 'id',
    as: 'client',
}
当我这样做
$lookup
时:

{
    "_id": ObjectId("5d779541bd4e75c58d598212")
    "client": ObjectId("5d779558bd4e75c58d598213")
}
{
    from: 'client',
    localField: 'client',
    foreignField: 'id',
    as: 'client',
}
我得到:

{
    "_id": ObjectId("5d779541bd4e75c58d598212")
    "client":[
        {
             ... client info wrapped in array
        }
     ]
}
这迫使我在查找阶段之后添加
$unwind

在本例中,这很好,因为我知道它是一个正则字段(不是数组)。但在其他集合中,我有
ObjectId的数组
,我不想
解开它们

我应该如何告诉
mongo
仅当它不是数组时才展开?

添加带有


查找总是返回一个数组,因为它不知道是一对一映射还是一对多映射。但是,我们可以确保查找返回单个文档,并且该文档将包含在常规查找中作为数组出现的所有文档

方法如下:

db.collection.aggregate([
    {
        $lookup:{
            "from":"client",
            "let":{
                "client":"$client"
            },
            "pipeline":[
                {
                    $match:{
                        $expr:{
                            $eq:["$id","$$client"]
                        }
                    }
                },
                {
                    $group:{
                        "_id":null,
                        "data":{
                            $push:"$$ROOT"
                        }
                    }
                },
                {
                    $project:{
                        "_id":0
                    }
                }
            ],
            "as":"clientLookup"
        }
    },
    {
        $unwind:"$clientLookup"
    }
]).pretty()
{
    "_id" : ObjectId("5d7792c6bd4e75c58d59820c"),
    "client" : 1,
    "clientLookup" : {
        "data" : [
            {
                "_id" : ObjectId("5d779322bd4e75c58d59820e"),
                "id" : 1,
                "name" : "Tony"
            },
            {
                "_id" : ObjectId("5d779322bd4e75c58d59820f"),
                "id" : 1,
                "name" : "Thor"
            },
            {
                "_id" : ObjectId("5d779322bd4e75c58d598210"),
                "id" : 1,
                "name" : "Natasha"
            }
        ]
    }
}
{
    "_id" : ObjectId("5d7792c6bd4e75c58d59820d"),
    "client" : 2,
    "clientLookup" : {
        "data" : [
            {
                "_id" : ObjectId("5d779322bd4e75c58d598211"),
                "id" : 2,
                "name" : "Banner"
            }
        ]
    }
}
查询分析:我们正在查找
客户机
集合,并在其中执行管道。该管道的输出将保存
data
字段中的每个匹配文档

数据集: 收藏:收藏

{
    "client":1
}
{
    "client":2
}
收集:客户端

{
    "id":1,
    "name":"Tony"
}
{
    "id":1,
    "name":"Thor"
}
{
    "id":1,
    "name":"Natasha"
}
{
    "id":2,
    "name":"Banner"
}
输出:

db.collection.aggregate([
    {
        $lookup:{
            "from":"client",
            "let":{
                "client":"$client"
            },
            "pipeline":[
                {
                    $match:{
                        $expr:{
                            $eq:["$id","$$client"]
                        }
                    }
                },
                {
                    $group:{
                        "_id":null,
                        "data":{
                            $push:"$$ROOT"
                        }
                    }
                },
                {
                    $project:{
                        "_id":0
                    }
                }
            ],
            "as":"clientLookup"
        }
    },
    {
        $unwind:"$clientLookup"
    }
]).pretty()
{
    "_id" : ObjectId("5d7792c6bd4e75c58d59820c"),
    "client" : 1,
    "clientLookup" : {
        "data" : [
            {
                "_id" : ObjectId("5d779322bd4e75c58d59820e"),
                "id" : 1,
                "name" : "Tony"
            },
            {
                "_id" : ObjectId("5d779322bd4e75c58d59820f"),
                "id" : 1,
                "name" : "Thor"
            },
            {
                "_id" : ObjectId("5d779322bd4e75c58d598210"),
                "id" : 1,
                "name" : "Natasha"
            }
        ]
    }
}
{
    "_id" : ObjectId("5d7792c6bd4e75c58d59820d"),
    "client" : 2,
    "clientLookup" : {
        "data" : [
            {
                "_id" : ObjectId("5d779322bd4e75c58d598211"),
                "id" : 2,
                "name" : "Banner"
            }
        ]
    }
}

为什么要返回带有数组或对象的字段。我希望Mongo保持数据的“形状”:当我有{client:ObjectId(“…”)时,当找不到
客户机时,我希望收到
null
,或者直接收到
{client:{all the client fields}
,但如果我的原始字段是
{clients:[ObjectId(…),ObjectId(…])
然后我希望它返回
{clients:[{…},{…}]}
基本上我想要与
mongoose.populate相同的行为,但是在mongo服务器端不知道为什么要这样做,但是可以这样做
db.collection.aggregate([{$project:{$collection:{$cond:[{$eq:[{$size:$collection”},1]},{$arrayElemAt:[“$collection”,0]},“$collection”]}]
@Ashh可能有用,但如果原始(“待填充”字段)最初是一个数组(恰好长度为1),它仍然会导致问题因为现在如果我们尝试填充它并使用该代码段,它会将其转换为常规对象基本上我希望mongo这样做:如果原始非数组,则将其保留为非数组。如果它是数组,则返回为数组。不幸的是,这是不可能的,因为
$lookup
不返回而不是数组。这仍然是相同的问题。我有要知道我“填充”的字段最初是常规字段还是数组。因为如果我对数组使用相同的查询,它将只返回第一个“填充”项。只有一个问题您的架构类型是clientId:ObjectId()还是clientId:[ObjectId(),ObjectId(),,,,,,,]?