【问题标题】:How can i get all the results using Mongodb Left join as well as conditions?如何使用 Mongodb Left join 以及条件获得所有结果?
【发布时间】:2020-05-31 14:12:22
【问题描述】:

我有两张桌子。 1) 房间列表 2) 房间用户。这里的左表将是 roomList。即使连接的表结果为空,是否可以获取所有结果?

我目前正在使用聚合:$lookup、$unwind、$match。

房间列表

const roomInfo = new mongoose.Schema({
    roomName: {
        type: String,
        trim: true,
        required: true
    },
    currentMembers: {
        type: Number,
        required: true
    },
    createdBy: {
        type: mongoose.Schema.ObjectId,
        required: true,
        ref: "User"
    },
    creationDate: {
        type: Date,
        trim: true
    },
    status: {
        type: Number,
        required: true,
        default: 1
    }
});

房间用户

const roomUser = new mongoose.Schema({
    roomId: {
        type: mongoose.Schema.ObjectId,
        required: true,
        ref: "RoomInfo"
    },
    userId: {
        type: mongoose.Schema.ObjectId,
        required: true,
        ref: "User"
    },
    joiningDate: {
        type: Date,
        trim: true
    },
    leavingDate: {
        type: Date,
        trim: true
    },
    requestDate:{
        type:Date,
        trim:true
    },
    status: {
        type: Number,
        default: 0 
    }

我想要类似于这个 mysql 查询的结果。

SELECT * FROM roomList LEFT JOIN roomUser ON roomUser.roomId = roomList.id WHERE roomUser.userId = 123 AND roomList.status = 1。

【问题讨论】:

  • 我终于明白了,使用所谓的 JOIN 来解决这个问题是如此困难(砰砰砰)。我使用猫鼬子文档做到了。现在我的收藏看起来像这样:

标签: mongodb mongoose


【解决方案1】:

它可以通过多个聚合阶段来完成。

  1. $match by roomUser id
  2. $lookup by room_id
  3. $unwind 找到的房间
  4. $匹配状态
  5. $replaceRoot 推广房间
db.roomUser.aggregate([
    {
        "$match": {
            "_id": ObjectId("5d3473a686041613147424ad")
        }
    },
    {
        "$lookup": {
            "from": "roomList",
            "localField": "room_id",
            "foreignField": "_id",
            "as": "r"
        }
    },
    {
        "$unwind": "$r"
    },
    {
        "$match": {
            "r.status": 1
        }
    },
    {
        "$replaceRoot": {
            "newRoot": "$r"
        }
    }
])

我不知道猫鼬,希望你能想出猫鼬等效...

【讨论】:

    【解决方案2】:

    我终于明白了,使用所谓的 JOIN 来解决这个问题太难了(撞头)。我使用猫鼬子文档做到了。现在我的收藏看起来像这样:

    const mongoose = require('mongoose');
    const Schema = mongoose.Schema;
    const roomUsers = new Schema (
        {
            userId: {
                type: mongoose.Schema.ObjectId,
                required: true,
                ref: "User"
            },
            joiningDate: {
                type: Date,
                trim: true
            },
            leavingDate: {
                type: Date,
                trim: true
            },
            requestDate:{
                type:Date,
                trim:true
            },
            status: {
                type: Number,
                default: 0 // 0 for none, 1 for request, 2 for joined, 3 for blocked
            }
        }
    );
    
    const roomInfo = new mongoose.Schema({
        roomName: {
            type: String,
            trim: true,
            required: true
        },
        currentMembers: {
            type: Number,
            required: true
        },
        createdBy: {
            type: mongoose.Schema.ObjectId,
            required: true,
            ref: "User"
        },
        creationDate: {
            type: Date,
            trim: true
        },
        status: {
            type: Number,
            required: true,
            default: 1 // 1 for active, 2 for deactive
        },
        roomUsers:[roomUsers]
    });
    
    var roomInfp = mongoose.model("RoomInfo", roomInfo);
    module.exports = roomInfp;
    

    【讨论】:

      【解决方案3】:

      MongoDb 和 noSql 数据库的理念与 SQL 数据库不同。

      对于 SQL 数据库,我们应该创建两个表来存储 roomlist 一个 roomUser。 在 NoSQL 数据库中,您应该将用户数据存储在房间列表中、特殊条目(数组、新对象)中,或者创建一个新表来存储用户和房间列表之间的链接。

      之后,您应该可以进行查询了。

      最好的问候

      【讨论】:

      • 好的,我明白你的回答。但是,如果我想将 ROOMUSER 集合用于我的另一个目的,例如在没有复杂逻辑的情况下从特定房间中删除少数选定用户,那么程序会是什么?
      猜你喜欢
      • 1970-01-01
      • 2018-02-28
      • 2014-09-09
      • 1970-01-01
      • 2012-04-05
      • 1970-01-01
      • 2011-11-21
      • 1970-01-01
      相关资源
      最近更新 更多