Mongodb $lookup Not working with _id

后端 未结 7 2131
猫巷女王i
猫巷女王i 2020-12-31 09:43

wend try with this query, return the lookup is empty

db.getCollection(\'tests\').aggregate([
    {$match: {typet:\'Req\'}},
    {$project: {incharge:1}},
            


        
相关标签:
7条回答
  • 2020-12-31 10:19

    Your lookup query is perfect, but the problem is you are storing incharge as string into the db, whereas the _id : ObjectId('theID') is an Object and not just string and you cannot compare a string (' ') with an object ({ }). So, the best way is to store the incharge key as an object(mongoose.Schema.ObjectId) and not as string in the schema.

    0 讨论(0)
  • 2020-12-31 10:23

    Comparing a string with an ObjectId doesn't throw an error, rather sends an empty array in the aggregated output document. So you need to make sure that you have converted the string object id to mongodb's ObjectId:

    db.getCollection('tests').aggregate([
        {$match: {typet:'Req'}},
        {$set: {incharge: {$toObjectId: "$incharge"} }}, // keep the whole document structure, but replace `incharge` into ObjectId
        {$lookup:{
                from: "users",
                localField: "incharge", //this is the _id user from tests
                foreignField: "_id", //this is the _id from users
                as: "user"
        }}
    ])
    
    0 讨论(0)
  • 2020-12-31 10:25

    I finaly found the solution, is a problem with my Schema in mongoose with the ObjectId

    I change this

    var Schema = new Schema({
        name: { type: String, required: true},
        incharge: { type: String, required: true},
    });
    

    with this

    var Schema = new Schema({
        name: { type: String, required: true},
        incharge: { type: mongoose.Schema.ObjectId, required: true},
    });
    

    and is working

    0 讨论(0)
  • 2020-12-31 10:29

    try changing type of incharge which is string to ObjectId in aggregate function like this

    { 
        $project : {
            incharge : {
                $toObjectId : "$incharge"
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-31 10:36

    You just have to use "_id.str" and work will be done.

    db.getCollection('tests').aggregate([
    {$match: {typet:'Req'}},
    {$project: {incharge:1}},
    {$lookup:{
            from: "users",
            localField: "incharge", //this is the _id user from tests
            foreignField: "_id.str", //this is the _id from users
            as: "user"
    }}
    

    ])

    Works fine for me.

    0 讨论(0)
  • 2020-12-31 10:38

    First, assert that the type of the incharge field is mongoose.Schema.Types.ObjectId. If you still get an empty array back it might be because you are using the schema name you declared in NodeJS instead of the collection name used by MongoDB.

    Example from a UserSchema file:

    const mongoose = require('mongoose')
    const Schema = mongoose.Schema
    
    const UserSchema = new Schema({
      name: { 
        type: String, 
        required: true
      },
      incharge: { 
        type: Schema.Types.ObjectId, 
        required: true
      },
    })
    
    const User = mongoose.model('User', UserSchema)
    module.exports = User
    

    The model above is named User by mongoose but the corresponding collection in mongoDB is named users. The resulting $lookup is written as:

    $lookup:{
      from: "users",           // name of mongoDB collection, NOT mongoose model
      localField: "incharge",  // referenced users _id in the tests collection
      foreignField: "_id",     // _id from users
      as: "user"               // output array in returned object
    }
    



    https://mongoosejs.com/docs/models.html
    https://mongoosejs.com/docs/schematypes.html

    0 讨论(0)
提交回复
热议问题