简体   繁体   中英

Populate data using another collection array in mongoose

My database Collections:

namelists:

{
    "_id": {
        "$oid": "5bd587adfb6fc074abb12cb2"
    },
    "name": "name 1",
    "year": "3",
    "id": "101"
}
,
{
    "_id": {
        "$oid": "5bd587cffb6fc074abb12cb8"
    },
    "name": "name 2",
    "year": "4",
    "id": "102"
},
{
    "_id": {
        "$oid": "5bd587e9fb6fc074abb12cbe"
    },
    "name": "name 3",
    "year": "2",
    "id": "103"
}

winners:

{
    "_id": {
        "$oid": "5bd58921fb6fc074abb12ce8"
    },
    "id": "301",
    "winner": [
        "101",
        "102"
    ]
}

I need module which traverse the array(id field) in the winner collection and find the data in namelist collection that matches(id field in namelist collection) the array(id) in the winner collection.

//I have two Schema namelist and winner

var Schema = mongoose.Schema;

var namelist = new Schema({
  _id: mongoose.Schema.ObjectId,
  id: String,
  name: String, 
  year: String
},
  {
  strict: false
});
var Namelist = mongoose.model('namelist', namelist);

var winner = new Schema({
  _id: mongoose.Schema.ObjectId,
  id: String,
  winner:[ String ]
},
  {
  strict: false
});
var Winner = mongoose.model('winner', winner);

//populate part

Namlist.find({ id: id }).
  populate('winner').
  exec(function (err, data) {
    if (err) return handleError(err);
    console.log(data);

  });

I need module which traverse the array(id filed) in the winner collection and find the data in namelist collection that matches(id field in namelist collection) the array(id) in the winner collection.

Expected Output

{
    "_id": {
        "$oid": "5bd587adfb6fc074abb12cb2"
    },
    "name": "name 1",
    "year": "3",
    "id": "101"
}
,
{
    "_id": {
        "$oid": "5bd587cffb6fc074abb12cb8"
    },
    "name": "name 2",
    "year": "4",
    "id": "102"
}

Except id:103 it should display other data using the winner collection

Thanks in Advance

To use .populate() in mongoose you need to define a reference between entities using ref as the documentation states ( here ). In this case you can use regular $lookup to merge the data from both collections and then you can $unwind and $replaceRoot to get items from namelists as a result. Try:

let result = await Winner.aggregate([
        { $match: { id: "301" } },
        { $lookup: { from: "namelists", localField: "winner", foreignField: "id", as: "winner"  } },
        { $unwind: "$winner" },
        { $replaceRoot: { newRoot: "$winner" } }
    ]);
console.log(result);

or using the old, callback style:

Winner.aggregate([
        { $match: { id: "301" } },
        { $lookup: { from: "namelists", localField: "winner", foreignField: "id", as: "winner"  } },
        { $unwind: "$winner" },
        { $replaceRoot: { newRoot: "$winner" } }
    ], function(err, result){
  console.log(result);
});

Prints:

[ { _id: 5bd587adfb6fc074abb12cb2,
    name: 'name 1',
    year: '3',
    id: '101' },
{ _id: 5bd587cffb6fc074abb12cb8,
    name: 'name 2',
    year: '4',
    id: '102' } ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM