Как я могу отфильтровать массив событий по общему полю _id? - PullRequest
0 голосов
/ 27 апреля 2019

У меня есть такой вывод, но я хочу отфильтровать массив событий по _id, который совпадает с родительским объектом _id. Я хочу отфильтровать его в соответствии с этим условием.

[
    {
        "_id": "5cc45eb430aaba3cdc045dc0" ,
        "word": "Pasta",
        "translate": "Makarna",
        "kind": "İsim",
        "exampleSentence": "asljdalsd",
        "__v": 0,
        "events": [
            {
                "_id": "5cc45eb430aaba3cdc045dc0",
                "createdAt": "2019-04-27T13:52:15.721Z",
                "TenMinutesLater": "2019-04-27T13:52:25.721Z",
                "OneWeekLater": "2019-05-04T13:52:15.721Z",
                "OneMonthLater": "2019-05-27T13:52:15.721Z",
                "FourMonthLater": "2019-08-27T13:52:15.721Z",
                "__v": 0
            },
            {
                "_id": "5cc45ee630aaba3cdc045dc1",
                "createdAt": "2019-04-27T13:52:15.721Z",
                "TenMinutesLater": "2019-04-27T13:52:25.721Z",
                "OneWeekLater": "2019-05-04T13:52:15.721Z",
                "OneMonthLater": "2019-05-27T13:52:15.721Z",
                "FourMonthLater": "2019-08-27T13:52:15.721Z",
                "__v": 0
            }
        ]
    }
]

Я хочу отфильтровать массив событий, который имеет то же свойство _id, что и родительский объект _id. Как должен соответствовать мой запрос тому, что я хочу?

это мой запрос

Word.find({ _id: req.params.id }, (err, words) => {
    if (err) {
      console.log(err);
    }
    const uid = words.map(word => word._id);
    console.log(req.params.id);
    Word.aggregate([
      {
        $match: {
          _id: {
            $in: uid.map(function(id) {
              return new mongoose.Types.ObjectId(id);
            })
          }
        }
      },
      {
        $lookup: {
          from: "tests",
          localField: "eventId",
          foreignField: "_id.str",
          as: "events"
        }
      }
    ])
      .then(data => {
        res.json(data);
      })
      .catch(err => {
        throw err;
      });
  });

Я хочу вывод, подобный этому. Как отфильтровать его с помощью _id родительского объекта?

[
    {
        "_id": "5cc45eb430aaba3cdc045dc0" ,
        "word": "Pasta",
        "translate": "Makarna",
        "kind": "İsim",
        "exampleSentence": "asljdalsd",
        "__v": 0,
        "events": [
            {
                "_id": "5cc45eb430aaba3cdc045dc0",
                "createdAt": "2019-04-27T13:52:15.721Z",
                "TenMinutesLater": "2019-04-27T13:52:25.721Z",
                "OneWeekLater": "2019-05-04T13:52:15.721Z",
                "OneMonthLater": "2019-05-27T13:52:15.721Z",
                "FourMonthLater": "2019-08-27T13:52:15.721Z",
                "__v": 0
        ]
    }
]

Ответы [ 2 ]

0 голосов
/ 28 апреля 2019

Спасибо, но я наконец-то решил проблему следующим образом. Работает отлично

Word.find({ _id: req.params.id }, (err, words) => {
    if (err) {
      console.log(err);
    }
    const uid = words.map(word => word._id);
    Word.aggregate([
      {
        $match: {
          _id: {
            $in: uid.map(function(id) {
              return mongoose.Types.ObjectId(id);
            })
          }
        }
      },
      {
        $lookup: {
          from: "tests",
          localField: "_id.str",
          foreignField: "eventId",
          as: "events"
        }
      },
      {
        $addFields: {
          events: {
            $filter: {
              input: "$events",
              as: "event",
              cond: {
                $eq: ["$$event._id", mongoose.Types.ObjectId(req.params.id)]
              }
            }
          }
        }
      }
    ])
      .then(data => {
        res.json(data);
      })
      .catch(err => {
        throw err;
      });
  });

0 голосов
/ 27 апреля 2019

Здесь $ lookup вернет все события, которые соответствуют условиям локального / внешнего поля, как вы, возможно, уже знаете. Если вы хотите отфильтровать результаты по некоторым другим критериям (что не очень понятно из вашего описания), вы можете использовать функцию конвейера в объединенной коллекции (представленной в 3.6). Пример конвейера в $ lookup (взятый с официального сайта) будет выглядеть следующим образом. Итак, как вы можете видеть, вы можете выполнить сопоставление в объединенной коллекции и отфильтровать ваши события.

db.orders.aggregate([
   {
      $lookup:
         {
           from: "warehous`enter code here`es",
           let: { order_item: "$item", order_qty: "$ordered" },
           pipeline: [
              { $match:
                 { $expr:
                    { $and:
                       [
                         { $eq: [ "$stock_item",  "$$order_item" ] },
                         { $gte: [ "$instock", "$$order_qty" ] }
                       ]
                    }
                 }
              },
              { $project: { stock_item: 0, _id: 0 } }
           ],
           as: "stockdata"
         }
    }
])
...