MongoDB增删改查等等一些...

Step1: 设计表

给定数据模型:用户-部门,多对多关系。

用户的departments属性是一个数组,表示用户的一个或多个部门。

//用户表字段
user{
    id: String, //用户编号
    name: String,
    departments: Array, //用户的部门数组
    gender: String,
    birthDate: Date,
    description: String
}

//部门表字段
department{
    id: String, //部门编号
    name: String,
    description: String
}

其中departments字段存储部门的_id

Step2: 表内容批量生成

1.插入

首先先定义用户数组user,然后循环生成各字段数据,存入user中,最后使用mongo的insertMany()方式,批量插入。

部门表也类似。

//------------------------生成用户表---------------------------------//
var users = []
//用户编号以流水号自增,用户名也加入数字,仅作不同区分,性别统一插入为'male'
for(i = 1; i < 100; i++){
  users[i - 1] = (
    {
      id:"20200811" + i,
      name:"bob" + i,
      gender:"male",
      birthDate:new Date(),
      departments:[],
      description:"this is the " + i + "th user that inserted in"
    }
  )
}
//将用户数组直接用insertMany批量插入
db.user.insertMany(users)

//------------------------生成部门表---------------------------------//
var depts = []
for(i = 1; i < 11; i++){
  depts[i - 1] = (
    {
      id: i,
      name:"deptNo." + i,
      users:[],
      description:"this is the " + i + "th department"
    }
  )
}
db.department.insertMany(depts)
2.更新

更新id为偶数的用户,将性别gender字段更新为female

var count = db.user.find().count()
//更新id为双数的用户gender字段
for (i = 1; i <= count; i++){
  if ( i % 2 == 0){
    db.user.update(
      {
        id: "20200811" + i
      },
      {
        /**
         * field: The field name
         * expression: The expression.
         */
        $set: {
          gender: "female"
        }
      }
    )
  }
}

Step3: 插入用户-部门关联数据

为用户表中每个用户文档中的department字段,随机分配三个部门表的_id。部门表id的随机查找输出是使用aggregate([{$sample:{size:n}}])实现,并保存至depts变量中,值得注意的是:depts变量中保存的并不是直接的部门文档数据,具体的部门文档数据是在属性_batch,然后对文档数据进行遍历,取出_id数组idList,_最终将_id数组保存至用户文档中。

db.user.find().forEach(
    //为每个用户随机分配三个部门
    function(item){
        var depts = []
        depts = db.department.aggregate([
            {$sample: {size: 3}}
        ])

        idList = []

        depts._batch.forEach(
            function(dept){
                idList.push(dept._id)
            }
        )
        //更新该用户的部门列表
        db.user.update(
            {id:item.id},
            {$set:{department:idList}}
        )
    }
)

插入之后的结果如下

可以看出,用户文档中的department属性已经加入了随机的三个部门文档的_id。

/* 1 */
{
    "_id" : ObjectId("5f3263d90438fed32d60c864"),
    "id" : "202008111",
    "name" : "bob1",
    "gender" : "male",
    "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
    "department" : [ 
        ObjectId("5f3264770438fed32d60c92f"), 
        ObjectId("5f3264770438fed32d60c931"), 
        ObjectId("5f3264770438fed32d60c92d")
    ],
    "description" : "this is the 1th user that inserted in"
}

/* 2 */
{
    "_id" : ObjectId("5f3263d90438fed32d60c865"),
    "id" : "202008112",
    "name" : "bob2",
    "gender" : "female",
    "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
    "department" : [ 
        ObjectId("5f3264770438fed32d60c934"), 
        ObjectId("5f3264770438fed32d60c92e"), 
        ObjectId("5f3264770438fed32d60c930")
    ],
    "description" : "this is the 2th user that inserted in"
}

/* 3 */
{
    "_id" : ObjectId("5f3263d90438fed32d60c866"),
    "id" : "202008113",
    "name" : "bob3",
    "gender" : "male",
    "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
    "department" : [ 
        ObjectId("5f3264770438fed32d60c92d"), 
        ObjectId("5f3264770438fed32d60c92f"), 
        ObjectId("5f3264770438fed32d60c932")
    ],
    "description" : "this is the 3th user that inserted in"
}

/* 4 */
{
    "_id" : ObjectId("5f3263d90438fed32d60c867"),
    "id" : "202008114",
    "name" : "bob4",
    "gender" : "female",
    "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
    "department" : [ 
        ObjectId("5f3264770438fed32d60c931"), 
        ObjectId("5f3264770438fed32d60c92d"), 
        ObjectId("5f3264770438fed32d60c92e")
    ],
    "description" : "this is the 4th user that inserted in"
}

/* 5 */
{
    "_id" : ObjectId("5f3263d90438fed32d60c868"),
    "id" : "202008115",
    "name" : "bob5",
    "gender" : "male",
    "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
    "department" : [ 
        ObjectId("5f3264770438fed32d60c933"), 
        ObjectId("5f3264770438fed32d60c92e"), 
        ObjectId("5f3264770438fed32d60c92b")
    ],
    "description" : "this is the 5th user that inserted in"
}
3.查询

希望的查询结果:查询名称为deptNo1的部门下的所有用户

$lookup

使用Mongo的聚合方法aggregate()来实现关联查询与字段显示,其中$lookup关键字表示多表关联查询,from表示需要关联的表department(base表为user),localField表示base表需要关联的字段,foreign表示关联的表的对应字段。

因为user表中存储的是department表中的_id属性数组:departments,所以localFieldforeignField需要填入_iddepartments字段。

as表示在查询后,将department中的文档记录以user的一个属性显示。下面的代码中选择直接覆盖原属性departments来显示。

$match

$match表示查询的匹配条件,这里选择匹配关联表department中的名称为deptNo1

limit

$skip:n方法表示跳过前n个数据,不进行罗列。$limit:n方法表示只显示查询到的前n个数据,结合skiplimit可以很简洁的实现分页操作。

如每页显示20条,显示第3页的数据,那么```limit:20```就可以实现。

skip, limit, sort的优先级为:sort, skip, limit

$unwind

因为部门信息是以数组形式存储在用户表中,而数组中每个部门都是不同的,因此可以使用$unwind方式首先将数组拆分开,与用户文档一一对应,然后再去关联查询匹配,分页等,数据的结构更加的简洁。

db.user.aggregate(
    [
    {
        $unwind: "$departments"
    },
    {
        $lookup:{
            from:"department",
            localField:"departments",
            foreignField:"_id",
            as:"departments"
        }
    },
    //查询部门名称为deptNo.2的关联后文档数据
    {
        $match:{
            "department.name":{$eq:"deptNo.2"}
            }
    },
    {
        $skip:9
    },
    {
        $limit:3
    }
    ]
)

查询条件:找出部门名为deptNo2的用户列表,并给出deptNo2的用户信息。

分页参数:第4页,每页显示3条数据。

查询结果如下:

/* 1 */
{
    "_id" : ObjectId("5f3263d90438fed32d60c894"),
    "id" : "2020081149",
    "name" : "bob49",
    "gender" : "male",
    "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
    "department" : [ 
        {
            "_id" : ObjectId("5f3264770438fed32d60c92c"),
            "id" : 2.0,
            "name" : "deptNo.2",
            "description" : "this is the 2th department"
        }
    ],
    "description" : "this is the 49th user that inserted in"
}

/* 2 */
{
    "_id" : ObjectId("5f3263d90438fed32d60c899"),
    "id" : "2020081154",
    "name" : "bob54",
    "gender" : "female",
    "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
    "department" : [ 
        {
            "_id" : ObjectId("5f3264770438fed32d60c92c"),
            "id" : 2.0,
            "name" : "deptNo.2",
            "description" : "this is the 2th department"
        }
    ],
    "description" : "this is the 54th user that inserted in"
}

/* 3 */
{
    "_id" : ObjectId("5f3263d90438fed32d60c89b"),
    "id" : "2020081156",
    "name" : "bob56",
    "gender" : "female",
    "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
    "department" : [ 
        {
            "_id" : ObjectId("5f3264770438fed32d60c92c"),
            "id" : 2.0,
            "name" : "deptNo.2",
            "description" : "this is the 2th department"
        }
    ],
    "description" : "this is the 56th user that inserted in"
}

Step4: 交换部门1与部门2的用户

思考:部门是以数组的形式作为用户的属性,那么对不同部门用户之间的交换,本质上可以转化为用户的部门_id的交换。

交换的主要步骤如下:

1.先找出部门1与部门2的_id

2.再找出部门1与部门2的用户

3.删除原有用户表中部门1与部门2的_id

4.将未删除前原用户具有部门1_id的,删除后,追加部门2的_id,将未删除前原用户具有部门2_id的,删除后,追加部门1的_id

实际上步骤复杂了,其实可以直接对用户部门列表进行swap操作。

//findOne找出部门1的_id
var depart1 = db.department.findOne(
    {
        "name": "deptNo.1"
    }
)._id

//findOne找出部门2的_id
var depart2 = db.department.findOne(
    {
        "name": "deptNo.2"
    }
)._id

//找出属于部门1的所有用户
var user_depart1 = db.user.find(
    {
        "department":depart1
    }
)

//找出属于部门2的所有用户
var user_depart2 = db.user.find(
    {
        "department": depart2
    }
)
//输出部门1与部门2的用户
user_depart1.toArray()
user_depart2.toArray()

//删除所有用户中部门1与部门2的信息
db.user.updateMany(
    {

    },
    {
        $pull:{
            "department": {
                $in: [depart1,depart2]
            }
        }
    }
)


//将原部门1的用户加入部门2
user_depart1.toArray().forEach(
    function(item){
        db.user.update(
            {
                "_id": item._id
            },
            {
                $push:{
                    "department": depart2
                }
            }
        )
    }
)

//将原部门2的用户加入部门1
user_depart2.toArray().forEach(
    function(item){
        db.user.update(
            {
                "_id": item._id
            },
            {
                $push:{
                    "department": depart1
                }
            }
        )
    }
)

上述代码中,使用

user_depart1.toArray()
user_depart2.toArray()

来输出每个部门用户。

输出结果验证

toArray()的输出是在交换之前,因此为了获得交换后的部门下用户结果,只需执行两次即可。第一次是未交换的,第二次是进行第二次交换之前的,即前一次的输出结果。

原先部门1的用户(前5个)

user_depart1.toArray()

    {
        "_id" : ObjectId("5f3263d90438fed32d60c868"),
        "id" : "202008115",
        "name" : "bob5",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c933"), 
            ObjectId("5f3264770438fed32d60c92e"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 5th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c86a"),
        "id" : "202008117",
        "name" : "bob7",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c934"), 
            ObjectId("5f3264770438fed32d60c933"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 7th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c86d"),
        "id" : "2020081110",
        "name" : "bob10",
        "gender" : "female",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c930"), 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 10th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c86f"),
        "id" : "2020081112",
        "name" : "bob12",
        "gender" : "female",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c930"), 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 12th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c874"),
        "id" : "2020081117",
        "name" : "bob17",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c934"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 17th user that inserted in"
    },

原先部门2的用户(前5个)

user_depart2.toArray()

    {
        "_id" : ObjectId("5f3263d90438fed32d60c86c"),
        "id" : "202008119",
        "name" : "bob9",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c931"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 9th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c86e"),
        "id" : "2020081111",
        "name" : "bob11",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c92d"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 11th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c870"),
        "id" : "2020081113",
        "name" : "bob13",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c933"), 
            ObjectId("5f3264770438fed32d60c931"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 13th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c875"),
        "id" : "2020081118",
        "name" : "bob18",
        "gender" : "female",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92e"), 
            ObjectId("5f3264770438fed32d60c930"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 18th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c878"),
        "id" : "2020081121",
        "name" : "bob21",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92e"), 
            ObjectId("5f3264770438fed32d60c930"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 21th user that inserted in"
    },

更改后的部门1用户:

    {
        "_id" : ObjectId("5f3263d90438fed32d60c86c"),
        "id" : "202008119",
        "name" : "bob9",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c931"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 9th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c86e"),
        "id" : "2020081111",
        "name" : "bob11",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c92d"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 11th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c870"),
        "id" : "2020081113",
        "name" : "bob13",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c933"), 
            ObjectId("5f3264770438fed32d60c931"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 13th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c875"),
        "id" : "2020081118",
        "name" : "bob18",
        "gender" : "female",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92e"), 
            ObjectId("5f3264770438fed32d60c930"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 18th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c878"),
        "id" : "2020081121",
        "name" : "bob21",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92e"), 
            ObjectId("5f3264770438fed32d60c930"), 
            ObjectId("5f3264770438fed32d60c92b")
        ],
        "description" : "this is the 21th user that inserted in"
    },

更改后的部门2用户:

    {
        "_id" : ObjectId("5f3263d90438fed32d60c868"),
        "id" : "202008115",
        "name" : "bob5",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c933"), 
            ObjectId("5f3264770438fed32d60c92e"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 5th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c86a"),
        "id" : "202008117",
        "name" : "bob7",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c934"), 
            ObjectId("5f3264770438fed32d60c933"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 7th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c86d"),
        "id" : "2020081110",
        "name" : "bob10",
        "gender" : "female",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c930"), 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 10th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c86f"),
        "id" : "2020081112",
        "name" : "bob12",
        "gender" : "female",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c930"), 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 12th user that inserted in"
    },
    {
        "_id" : ObjectId("5f3263d90438fed32d60c874"),
        "id" : "2020081117",
        "name" : "bob17",
        "gender" : "male",
        "birthDate" : ISODate("2020-08-11T09:24:41.589Z"),
        "department" : [ 
            ObjectId("5f3264770438fed32d60c92f"), 
            ObjectId("5f3264770438fed32d60c934"), 
            ObjectId("5f3264770438fed32d60c92c")
        ],
        "description" : "this is the 17th user that inserted in"
    },

可以看出,部门1与部门2的结果发生了交换。

全部评论

相关推荐

11-08 10:39
门头沟学院 C++
点赞 评论 收藏
分享
11-01 20:03
已编辑
门头沟学院 算法工程师
Amazarashi66:这种也是幸存者偏差了,拿不到这个价的才是大多数
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务