简体   繁体   中英

How create mongodb aggregate query for multiple collections

I have two models

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 },
});

My collections

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

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

I want to combine a field textKey from collection text with array texts from collection story and write field text from collection text into result query. I have to get a array of object

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

I tried to create a aggregate multiple collections

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

But i got an empty array. Where I made an error? How I can create a aggregate?

You can't lookup on an array, you could achieve what you want using this aggregation but it may be slow if you have big collections:

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
    }
  }
])

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