Mongodb - 查找引用文档并在其内部数组

时间:2017-04-02 18:33:47

标签: javascript mongodb mongoose mongodb-query aggregation-framework

所以我在mongodb中有这些数据:

流程文档:

process: {
    procnumber: '1',
    person: {
        $ref: 'person',
        $id: ObjectId("5126bc054aed4daf9e2ab772")
    }
}
process: {
    procnumber: '2',
    person: {
        $ref: 'person',
        $id: ObjectId("5126bc054aed4daf9e2ab996")
    }
}

个人文件:

person: {
    _id: ObjectId("5126bc054aed4daf9e2ab772"),
    name:'person_1',
    obsarray:[{date:ISODate("2017-02-13"),obs:'1.this is one'},{date:ISODate("2017-02-20"),obs:'1.this is two'},{date:ISODate("2017-02-01"),obs:'1.this is three'}]
}
person: {
    _id: ObjectId("5126bc054aed4daf9e2ab996"),
    name:'person_2',
    obsarray:[{date:ISODate("2017-02-17"),obs:'2.this is one'},{date:ISODate("2017-02-27"),obs:'2.this is two'},{date:ISODate("2017-02-28"),obs:'2.this is three'}]
}

我想查询它以便查询返回Process和Person中的字段,同时让“obsarray”只返回具有最新日期的文档。

所需输出的示例:

{
procnum:'1',
person: {
    name:'person_1',
    obsarray: {
        date:ISODate("2017-02-20"),
        obs:'1.this is two'
    }
}

我尝试过使用聚合,但是我没有处理参考:

db.person.aggregate([
    {$match:{name:{$exists:true}}},
    {$unwind:'$obsarray' },
    {$sort:{'obsarray.date':-1}},
    {$group:{
        _id:'$_id',
        obsarray:{$first: '$obsarray.date'},
        name:{$first:'$name'}}
    }
])

有没有办法从'Process'填充'Person'引用然后应用聚合以使输出包含来自两个文档的字段?

1 个答案:

答案 0 :(得分:0)

您必须将DBRef更改为手动参考。像

这样的东西
var ProcessSchema = new mongoose.Schema({
    procnumber: String,
    person: {
     type: Schema.Types.ObjectId,        
     ref: 'Person'
    }
});

更新文档后,应如下所示。

process: {
    procnumber: '1',
    person: {
        _id: ObjectId("5126bc054aed4daf9e2ab772")
    }
}

现在,您可以使用$lookup从聚合查询中的其他集合中获取信息。

db.person.aggregate([
    {$match:{name:{$exists:true}}},
    {$lookup: {
        from: "process",
        localField: "_id",
        foreignField: "person._id",
        as: "person_process"}
    },
    {$unwind:'$person_process'},
    {$unwind:'$obsarray' },
    {$sort:{'obsarray.date':-1}},
    {$group:{
        _id:'$_id',
        obsarray:{$first: '$obsarray.date'},
        name:{$first:'$name'}},
        procnum:{$first:'$person_process.procnum'}}
    }
])