pfan123/Articles

Mongodb 对内嵌数组的增删改查操作

Opened this issue · 0 comments

先定义一份初始化,设置一个User类,其初始数据如下:

{ 
  arr: [ 1, 2 ],
  _id: 5ac5ee12a79131259413c40f,
  name: 'scy',
  __v: 0 
}

随后以初始数据为基,进行操作。

1、向内嵌数组添加数据

使用操作符 $push,向数组末尾添加数据 ,可重复

//第一个参数是匹配条件 第二个参数是具体操作向user里面的arr末尾追加元素3
User.update({name:"scy"},{$push:{"arr":3}});

执行结果

{ 
  arr: [ 1, 2, 3 ],
  _id: 5ac5f0d3db343b1888a8969d, 
  name: 'scy',
  __v: 0 
}

一次添加多个数据:

//两种方式都可以
User.update({name:"scy"},{$push:{"arr": [2,3]}});
User.update({name:"scy"},{$push:{"arr":{$each:[2,3]}}});

2、删除内嵌数组指定数据

使用操作符 $pull

//删除arr所有数据为2的元素*
User.update({name:"scy"},{$pull:{"arr":2}});

执行结果

{ arr: [ 1 ], _id: 5ac5f39fdad94e23e8de9aee, name: 'scy', __v: 0 }

如果数组元素是对象,可以根据对象属性操作:

//User数据结构
{
  name:"scy",
  mArray:[{age:13,weight:50},{age:13,weight:30}]
}
//删除所有weight属性值为30的对象
User.update({name:"scy"},{$pull:{"mArray":{"weight":30}}});

3、修改内嵌数组指定数据

//将数组里面的第一个元素1修改为2
User.update({"arr":{$all:[1]}},{$set:{"arr.$":2}});

//根据下标 将arr下标为1的元素修改为22
User.update({$set:{"arr.1":22}});

//将数组里面的元素1批量修改为2
User.updateMany({"arr":{$all:[1]}},{$set:{"arr.$":2}});

如果数组的元素是对象,如下:

{
  name:"scy",
  mArray:[{age:13,weight:50},{age:13,weight:30}]
}

修改操作如下:

//将第一个age为13的值修改为22
User.update({"mArray.age":13},{$set:{"mArray.$.age":22}});

//还可以这样 mArray.1.age 其中1是下标 
User.update({$set:{"mArray.1.age":22}});//将arr第二个元素对象的age改为22

//将第age为13的值修改为22
User.updateMany({"mArray.age":13},{$set:{"mArray.$.age":22}});

4、查询内嵌数组并返回指定的数据

使用 $size 返回指定数组长度的数据:

//$size限制比较大 下面表示查询数组长度为2的数据
User.find({arr:{$size:2}})

$slice 操作符比较强大:

//匹配到的user 将其数组截取第一个返回 如[1,1,2]返回[1]
User.findOne({name:"scy"},{arr:{$slice:1}});
//将匹配到的user的数组 截取返回后面两个元素  如[1,1,2]返回[1,2]
User.findOne({name:"scy"},{arr:{$slice:-2}});
//从数组的下表为1的元素开始 返回两个 如[1,3,2]返回[3,2]
User.findOne({name:"scy"},{arr:{$slice:[1,2]}});

5、mongodb 按照字段模糊查询方法

直接查询:

//值查询
db.student.find({name:{$regex:'jack', $options:'i'}})
db.student.find({name:{$regex:/jack.*/i}})
db.student.find({name:/jack/i})

//数组元素查询, 与值查询类似
db.school.find({students:/jack/i})

// 对数组对象查询
contacts:{
    [
        {
            address: "address1",
            name: "张三"
        },
        {
            address: "address2",
            name: "李四"
        },
        .....
    ]
}
db.collection.find({'contacts.name':{$regex:'张'}})

对比:

MySQL MongoDB
select * from student where name like ‘%jack%’ db.student.find({name:{$regex:/jack/}})
select * from student where name regexp ‘jack’ db.student.find({name:/jack/})

6、MongoDB对AND、OR、IN的操作

AND操作:

在MongoDB中向查询文档中加入多个键值对,将多个查询条件组合在一起,这样的条件会被解释成AND操作。例如,要想查询用户名为ickes而且年龄为25岁的用户。查询语句如下:

db.users.find({"name":"ickes","age":25})  

OR查询:

查询用户名为user1 或者 age为24的用户。查询语句如下:

db.users.find({"$or":[{"name":"user1"},{"age":24}]})  

IN和NOT IN操作:

其实IN就是对单个字段的OR的一种简写。

查询年龄等于16、24、32的用户。查询语句如下:

db.users.find({"age":{"$in":[16,24,32]}})  

查询年龄不等于13、17、21的用户。查询语句如下:

db.users.find({"age":{"$nin":[13,17,21]}})  

结合 $or and $in 复合操作

// 查询根据 tag|name 模糊查询图标库图标 满足endisable: true
db.repoicons.find({"$or":[{tags: {$regex: tag, $options:'i'} }, {name: {$regex: tag, $options:'i'}}], endisable: true}).populate('userInfo', {username: 1, nickname: 1, _id: 0})

MongoDB 操作命令

1、json 格式数据导入(mongoimport)

mongoimport --db database_name --collection collection_name --file path\file_name.json

其中 "database_name" 代表数据库的名字,"collection_name" 代表集合的名字,"path" 是要导入的 json 格式数据的路径。

2、bson 格式数据导入(mongorestore)

mongoimport --db database_name --collection collection_name path\file_name.bson 

其中 "database_name" 代表数据库的名字,"collection_name" 代表集合的名字,"path" 是要导入的 bson 格式数据的路径。

3、导出数据 json(mongoexport)

mongoexport --db database_name --collection collection_name --output path\file_name.json

其中 "database_name" 代表数据库的名字,"collection_name" 代表集合的名字,"path" 是要导入的 json 格式数据的路径。

参考资料:
mongoosejs
Mongoose 之 Population 使用
mongodb doc