簡體   English   中英

加入兩個 collections 並在 MongoDb 中應用一個條件

[英]Join two collections and apply a condition in MongoDb

我有兩個 collections:

  1. student_classes
[
    {
        '_id': ObjectId('60923c997b4d3205009a981a'),
        'studentId': ObjectId('608a42e8224c549ad9a9ab51'),
        'classId': ObjectId('60312a59c824a213c1d014af'),
    },
    {
        '_id': ObjectId('609392ad31db141f56afb043'),
        'studentId': ObjectId('608a42e8224c549ad9a9ab51'),
        'classId': ObjectId('60914922749cd2f796f01efe'),
    },
    {
        '_id': ObjectId('609392ad31db141f56afb044'),
        'studentId': ObjectId('608a42e8224c549ad9a9ab51'),
        'classId': ObjectId('6091468e749cd2f796f01efd'),
    },
];

和類集合:

[
    {
        '_id': ObjectId('60312a59c824a213c1d014af'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-03-18T07:10:00.628Z',
    },
    {
        '_id': ObjectId('6091468e749cd2f796f01efd'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-18T07:10:00.628Z',
    },
    {
        '_id': ObjectId('60914922749cd2f796f01efe'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-03-18T07:10:00.628Z',
    },
    {
        '_id': ObjectId('6091494a749cd2f796f01eff'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-20T07:10:00.628Z',
    },
    {
        '_id': ObjectId('60914953749cd2f796f01f00'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-22T07:10:00.628Z',
    },
    {
        '_id': ObjectId('60914957749cd2f796f01f01'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-24T07:10:00.628Z',
    },
    {
        '_id': ObjectId('6091495c749cd2f796f01f02'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-26T07:10:00.628Z',
    },
    {
        '_id': ObjectId('60914972749cd2f796f01f03'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-26T07:10:00.628Z',
    },
    {
        '_id': ObjectId('60914981749cd2f796f01f04'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-28T07:10:00.628Z',
    },
    {
        '_id': ObjectId('60914989749cd2f796f01f05'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-30T07:10:00.628Z',
    },
    {
        '_id': ObjectId('6091499f749cd2f796f01f06'),
        'name': 'Holistic Yoga For Beginners - Class',
        'classDateTime': '2021-05-19T07:10:00.628Z',
    },
];

我想 select 一個學生(來自 student_classes)的所有條目類,其中 classDateTime 大於特定日期。 兩個 collections 通過 student_classes.classId 和 classes._id 鏈接。

這是我迄今為止嘗試過的:

{
    $lookup:
        {
            from: 'classes',
            let: { classId: '$classId' },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $and:
                                [
                                    { $eq: ['$_id', '$$classId'] },
                                    { $gt: ['$classDateTime', '2021-05-05T06:35:05.226+00:00'] },
                                ],
                        },
                    },
                },
            ],
            as: 'classInfo',
        },
};

但這不起作用。 我仍然從 student_classes 集合中獲取所有記錄。 實現這一目標的正確方法是什么?

只需在查找階段之后放置匹配條件以過濾沒有空結果的類,

  { $lookup: { .. } },
  { $match: { classInfo: { $ne: [] } } }

操場

雖然您得到了答案,但您只需要在如下管道中的樣子之后匹配確保classInfo字段不為空:

蒙戈游樂場

我想建議您從class集合開始查詢,目前您正在查詢整個學生集合並對其進行$lookup 這是非常非常低效的。 特別是隨着student收藏規模的增加。

通過從classes集合開始查詢,您可以索引classDateTime並最初為您的管道獲取一個小得多的數據集,我將這樣做:

db.classes.aggregate([
  {
    $match: {
      classDateTime: {
        $gt: "2021-05-05T06:35:05.226+00:00"
      }
    }
  },
  {
    $lookup: {
      from: "students",
      localField: "_id",
      foreignField: "classId",
      as: "studentsInfo"
    }
  },
  {
    $unwind: "$studentsInfo"
  },
  {
    $replaceRoot: {
      newRoot: {
        "$mergeObjects": [
          "$studentsInfo",
          {
            name: "$name",
            classDateTime: "$classDateTime"
          }
        ]
      }
    }
  }
])

蒙戈游樂場

你需要先加入collections再做魔方的rest。 試試這個https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/

還有關於數據庫 model 設計的小通知,我建議您在 arrays 的幫助下嵌入文檔。 因此,您可以避免進行連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM