Как создать агрегированный запрос mongodb для нескольких коллекций

#mongodb #aggregate

#mongodb #агрегат

Вопрос:

У меня есть две модели

 export const StorySchema = new Schema({
  type: { type: String, required: true },
  texts: { type: Array, require: true },
});


export const TextSchema = new Schema({
  textKey: { type: String, required: true },
  text: { type: String, required: true },
});
 

Мои коллекции

 // stories
[
  {
    "type": "export",
    "texts": ["export", "download"]
  },
  ...
]

// Text
[
  {
    "textKey": "export",
    "text": "Export ....."
  },
  {
    "textKey": "download",
    "text": "Download ....."
  },
  ...
]
 

Я хочу объединить поле textKey из коллекции text с массивом texts из коллекции story и записать поле text из коллекции text в запрос результата. Я должен получить массив объектов

 [
  {
     "type": "export",
     "texts": ["Export .....", "Download ....."]
  },
  ...
]
 

Я попытался создать агрегированный запрос из нескольких коллекций

   public async getStoriesList(): Promise<Story[]> {
    return await this.storyModel.aggregate([{
      $lookup: {
        from: 'texts',
        localField: 'texts',
        foreignField: 'textKey',
        as: 'texts',
      },
    }]);
  }
 

Но я получил пустой массив. Где я допустил ошибку? Как я могу создать агрегат?

Ответ №1:

Вы не можете lookup использовать массив, вы могли бы достичь того, чего хотите, используя эту агрегацию, но это может быть медленным, если у вас большие коллекции:

 db.stories.aggregate([
  {
    "$unwind": "$texts"
  },
  {
    "$lookup": {
      "from": "texts",
      "localField": "texts",
      "foreignField": "textKey",
      "as": "data"
    }
  },
  {
    "$unwind": "$data"
  },
  {
    "$group": {
      "_id": "type",
      "texts": {
        "$push": "$data.text"
      }
    }
  },
  {
    "$project": {
      "type": "$_id",
      "_id": 0,
      "texts": 1
    }
  }
])