guy
guy

Reputation: 111

$lookup on ObjectId's in an array does not work

i have the same case as in this question: $lookup on ObjectId's in an array (i can't comment on the question since i don't have enough reputation... sorry for the duplication..) - but the query doesn't work for me and i get an empty array in the end of it.

i want to get a list of companies with a field of its positions, but the positions field is always empty on the following code. (i get the company fields, and with the $unwind - even the company fields are not returned).

what am i doing wrong?

mongoose version: 5.7.14 mongodb version: 4.2.3

i also tried a lot of combinations of aggregation and populate and none of them succeeded.

const schema = new Schema(
  {
    email: {
      type: String,
      required: true,
      unique: true
    },
    name: {
      type: String,
      required: true,
      unique: true
    },
    positionsIds: [{
      type: Schema.Types.ObjectId, 
      ref: 'Position',
      require: false
  }
);

module.exports = mongoose.model('Company', schema);

-----------------------------

const schema = new Schema(
  {
    title: {
      type: String,
      required: true
    },
    requirements: [{
      years: { type: Number, required: false },
      skill: { type: String, required: false },
    }],
    companyId: {
      type: Schema.Types.ObjectId, 
      ref: 'Company',
      required: true
    },
  }
);

module.exports = mongoose.model('Position', schema );

---------------------------

    let companies = await Company.aggregate([
      { 
        $lookup: 
        { 
          from: 'Position',
          localField: '_id',
          foreignField: 'companyId',
          as: 'positions' 
        }  
      },
      // {
      //     $unwind: '$positions' // - mess the query even more and return an empty array
      // },
      ]);


Upvotes: 1

Views: 96

Answers (1)

mickl
mickl

Reputation: 49985

Mongoose creates MongoDB collections based on convention. Position as model name gets translated into plural form positions so your query should look like:

{ 
    $lookup: { 
        from: 'positions',
        localField: '_id',
        foreignField: 'companyId',
        as: 'positions' 
    }  
}

The first argument is the singular name of the collection your model is for. ** Mongoose automatically looks for the plural, lowercased version of your model name. ** Thus, for the example above, the model Tank is for the tanks collection in the database.

Upvotes: 3

Related Questions