-1

我正在尝试对这两个集合进行左反连接。

我希望所有部门等于“IT”的用户不在结束时间 > 175 的会议中。无论是作为创建者还是接收者。所以基本上谁在最后 xxx 时间没有参加过会议。

基于以下集合: John 将被检索,因为他是 IT 部门的一部分,并且在“175”之后没有成为接收者或创建者。简在 175 之后有一个结束时间并且在 IT 部门,所以不会被检索到比尔是财务部门的一员,所以即使他没有去过也没关系 Bob 有一个结束时间在 175 之后的时间并且在 IT 部门,所以不会被找回 Mary 在 IT 部门,并且没有参加任何会议,所以她被找回了。

用户收藏:

[
  {
    _id: ObjectId("1"),
    name: "john",
    department: 'IT'
  },
  {
    _id: ObjectId("2"),
    name: "jane",
    department: 'IT'
  },
  {
    _id: ObjectId("3"),
    name: "bill",
    department: 'finance'
  },
  {
    _id: ObjectId("4"),
    name: "Bob",
    department: 'IT'
  },
  {
    _id: ObjectId("5"),
    name: "Mary",
    department: 'IT'
  }
]

会议收藏:

[
  {
    _id: ObjectId("a"),
    endedAt: 100,
    creator_id: ObjectId("1"),
    receiver_id: ObjectId("2")
  },
  {
    _id: ObjectId("b"),
    endedAt: 150,
    creator_id: ObjectId("1"),
    receiver_id: ObjectId("3")
  },
  {
    _id: ObjectId("c"),
    endedAt: 200,
    creator_id: ObjectId("4"),
    receiver_id: ObjectId("2")
  },
  {
    _id: ObjectId("d"),
    endedAt: 250,
    creator_id: ObjectId("2"),
    receiver_id: 
  }
]

输出:

[
  {
    _id: ObjectId("1"),
    name: "john",
    department: 'IT'
  },
  {
    _id: ObjectId("5"),
    name: "Mary",
    department: 'IT'
  }
]

我的做法:

db.users.aggregate([
        {
            $match:
                {
                    type: 'IT'
                }
        },
        {
            $lookup:
                {
                    from: "meetings",
                    let:
                        {
                            userid: "$_id",
                        },
                    pipeline: [
                        { $match:
                                { $expr:
                                    {
                                        $and:[
                                            {
                                                $or: [
                                                    { $eq: ["$receiver_id", "$$userid"] },
                                                    { $eq: ["$creator_id", "$$userid"] },
                                                ]
                                            },
                                            { $gt: ["$endAt", 175] }
                                        ]
                                    }
                                }
                        }
                        ],
                    as: "result"
                }
        },

        {
            $unwind:
                {
                    path: "$result",
                    preserveNullAndEmptyArrays: true
                }
        },

        {
            $match:
                {
                    result: {$exists:false}
                }
        }
    ])
4

3 回答 3

1

总计的

db.users.aggregate([
  {
    "$match": {
      department: "IT"
    }
  },
  {
    "$lookup": {
      "from": "meeting",
      "localField": "_id",
      "foreignField": "creator_id",
      "as": "meeting_creator"
    }
  },
  {
    "$lookup": {
      "from": "meeting",
      "localField": "_id",
      "foreignField": "receiver_id",
      "as": "meeting_receiver"
    }
  },
  {
    "$match": {
      "$and": [
        {
          "meeting_creator.endedAt": {
            "$not": {
              "$gt": 175
            }
          }
        },
        {
          "meeting_receiver.endedAt": {
            "$not": {
              "$gt": 175
            }
          }
        }
      ]
    }
  },
  {
    "$project": {
      _id: 1,
      name: 1,
      department: 1
    }
  }
])

数据

db={
  "users": [
    {
      _id: "1",
      name: "john",
      department: "IT"
    },
    {
      _id: "2",
      name: "jane",
      department: "IT"
    },
    {
      _id: "3",
      name: "bill",
      department: "finance"
    },
    {
      _id: "4",
      name: "Bob",
      department: "IT"
    },
    {
      _id: "5",
      name: "Mary",
      department: "IT"
    }
  ],
  "meeting": [
    {
      _id: "a",
      endedAt: 100,
      creator_id: "1",
      receiver_id: "2"
    },
    {
      _id: "b",
      endedAt: 150,
      creator_id: "1",
      receiver_id: "3"
    },
    {
      _id: "c",
      endedAt: 200,
      creator_id: "4",
      receiver_id: "2"
    },
    {
      _id: "d",
      endedAt: 250,
      creator_id: "2",
      receiver_id: ""
    }
  ]
}

结果

[
  {
    "_id": "1",
    "department": "IT",
    "name": "john"
  },
  {
    "_id": "5",
    "department": "IT",
    "name": "Mary"
  }
]

mongoplayground

于 2021-09-30T05:55:36.717 回答
1

询问

  • 匹配“它”
  • join if >175 AND (userid in any of the 2 (creator/receiver))
    *它的查找管道,因为多个连接条件
  • 拒绝那些加入的人

测试代码在这里

db.users.aggregate([
  {
    "$match": {
      "department": {
        "$eq": "IT"
      }
    }
  },
  {
    "$lookup": {
      "from": "meetings",
      "let": {
        "userid": "$_id"
      },
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$and": [
                {
                  "$gt": [
                    "$endedAt",
                    175
                  ]
                },
                {
                  "$or": [
                    {
                      "$eq": [
                        "$$userid",
                        "$creator_id"
                      ]
                    },
                    {
                      "$eq": [
                        "$$userid",
                        "$receiver_id"
                      ]
                    }
                  ]
                }
              ]
            }
          }
        },
        {
          "$project": {
            "_id": 1
          }
        }
      ],
      "as": "meetings"
    }
  },
  {
    "$match": {
      "$expr": {
        "$eq": [
          "$meetings",
          []
        ]
      }
    }
  },
  {
    "$unset": [
      "meetings"
    ]
  }
])
于 2021-09-30T10:32:37.983 回答
0

这是我想出的最终工作的解决方案,有人知道什么是最有效的吗?

db.users.aggregate([
        {
            $match:
                {
                    type: 'IT'
                }
        },
        {
            $lookup:
                {
                    from: "meetings",
                    let:
                        {
                            userid: "$_id",
                        },
                    pipeline: [
                        { $match:
                                { $expr:
                                    {
                                        $and:[
                                            {
                                                $or: [
                                                    { $eq: ["$receiver_id", "$$userid"] },
                                                    { $eq: ["$creator_id", "$$userid"] },
                                                ]
                                            },
                                            { $gt: ["$endAt", 175] }
                                        ]
                                    }
                                }
                        }
                        ],
                    as: "result"
                }
        },

        {
            $unwind:
                {
                    path: "$result",
                    preserveNullAndEmptyArrays: true
                }
        },

        {
            $match:
                {
                    result: {$exists:false}
                }
        }
    ])
于 2021-09-30T16:56:52.793 回答