Объединение коллекций в mongodb с node js - PullRequest
1 голос
/ 13 апреля 2020

У меня есть две коллекции в mongodb "компоненты" и "планеры", которые я пытаюсь объединить (с отношением один ко многим). У меня есть следующий код, который получает данные о планере и компонентах отдельно от базы данных, однако после нескольких дней усилий я не могу понять, как соединить их вместе. Я предполагаю, что мне нужно использовать $ lookup для достижения желаемого результата, но любая помощь в создании кода будет принята с благодарностью.

мои модели выглядят следующим образом, и я пытаюсь объединить все записи компонентов в рамках соответствующего планера. поле планера в Компоненте содержит идентификатор соответствующего планера.

const airframeSchema = mongoose.Schema({
  name: { type: String, required: true },
  sNumber: { type: String, required: true },
  aStatus: { type: String, required: true },
  components: [ { 
    type: mongoose.Schema.Types.ObjectId, 
    ref: 'Component' } ]
});
module.exports = mongoose.model('Airframe', airframeSchema);

const componentSchema = mongoose.Schema({
  name: { type: String, required: true },
  serial: { type: String, required: true }, 
  type: { type: String, required: true },
  airFrame: { 
    type: mongoose.Schema.Types.ObjectId, 
    required: true,
    ref: 'Airframe'},
});

module.exports = mongoose.model('Component', componentSchema);

AirFramesService выглядит следующим образом. Я хотел бы объединить данные компонента в массив под названием «компонент».

  getAirframes() {
    this.http
      .get<{ message: string; airframes: any }>("http://3.135.49.46:8080/api/airframes")
      .pipe(
        map(airframeData => {
          return airframeData.airframes.map(airframe => {
            return {
              name: airframe.name,
              sNumber: airframe.sNumber,
              aStatus: airframe.aStatus,
              id: airframe._id,
            };
          });
        })
      )
      .subscribe(transformedAirframes => {
        this.airframes = transformedAirframes;
        this.airframesUpdated.next([...this.airframes]);
      });
  }

  getAirframeUpdateListener() {
    return this.airframesUpdated.asObservable();
  }

  getAirframe(id: string) {
    return this.http.get<{ _id: string; name: string; sNumber: string ; aStatus: string}>(
      "http://3.135.49.46:8080/api/airframes/" + id
    );
  }

Код маршрута планера выглядит следующим образом:

router.get("", (req, res, next) => {
  Airframe.find().then(documents => {
    res.status(200).json({
      message: "Airframes fetched successfully!",
      airframes: documents
    });
  });
});

, а вот код в файле компонента ts, который получает данные планера, выглядит следующим образом.

  constructor( public airframesService: AirframesService) {
    this.airframesService.getAirframes();
    this.airframesSub = this.airframesService.getAirframeUpdateListener()
      .subscribe((airframes: Airframe[]) => {
        this.isLoading = false;
        this.airframes = airframes;
        }, 0);
    });
  }

желаемый результат будет следующим (на данный момент я получаю только данные планера):

{
    _id: "123"
    name: "Airframe01"
    sNumber: "757"
    aStatus: "Active"
    id: "5e8052ad1fa18f1c73524664"
    components: [
      {
       name: "Left Tank",
       serial: "3456789", 
       type: "Landing Gear",
       airFrame: "5e8052ad1fa18f1c73524664"
       },
       {
       name: "Right Tank",
       serial: "45678", 
       type: "Landing Gear",
       airFrame: "5e8052ad1fa18f1c73524664"
       }
    ]
}

1 Ответ

0 голосов
/ 13 апреля 2020

В вашей структуре документов уже установлены отношения типа "один ко многим" между двумя моделями, вы можете использовать совокупность Mon goose, чтобы получить соединение, описанное вами в вопросе. Код заполнения должен быть где-то на маршруте планера, например:

router.get("", (req, res, next) => {
  // Notice the populate() method chain below
  Airframe.find().populate('components').then(documents => {
    // The documents output should have their "components" property populated
    // with an array of components instead of just Object IDs.
    res.status(200).json({
      message: "Airframes fetched successfully!",
      airframes: documents
    });
  });
});

Вы можете узнать больше о пн goose население здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...