Obeta

Mongodb使用教程

用了那么久MongoDB,今天就来总结一下它的一些常用使用方式,方便以后查询.

mongodb logo

创建数据库:

MongoDB 中 use DATABASE_NAME 用于创建数据库.该命令将创建一个新的数据库,如果它不存在,否则将返回现有的数据库.

// 创建一个数据库:obeta
use obeta
// 查看当前所在数据库命令:db
db;
// 检查数据库列表,使用命令show dbs.
show dbs

值得注意的是:创建的数据库 obeta 列表中是不存在的

// 要显示的数据库,需要把它插入至少一个文件.
db.obeta.insert({
	name: 'tutorials yiibai',
});

删除数据库

MongoDB 中 db.dropDatabase() 命令是用来删除一个现有的数据库.

// 先查看数据库
show dbs
// 选定数据库
use obeta

db.dropDatabase()命令将删除选定的数据库,如果还没有选择任何数据库,然后它会删除默认的 ' test' 数据库.

创建集合

MongoDB 中 db.createCollection(name, options) 是用来创建集合.

name 是要创建的集合的名称. options 是一个文件,用于指定配置的集合.

参数类型描述
nameString要创建的集合名称
OptionsDocument可选)指定有关内存大小和索引选项

option 参数是可选的,所以只需要到指定的集合名称.以下是可以使用的选项列表

字段类型描述
cappedBoolean(可选)如果为 true,则启用封顶集合,封顶集合是固定大小的集合,会自动覆盖最早的条目,当它达到其最大大小.如果指定 true,则需要也指定尺寸参数.
autoIndexIDBoolean(可选)如果为 true,自动创建索引_id 字段的默认值是 false
sizeNumber(可选),指定最大大小字节封顶集合,如果封顶如果是 true,那么你还需要指定这个字段
maxNumber(可选)指定封顶集合允许在文件的最大数量,当插入文档,MongoDB 第一检查大小字段封顶集合,然后它会检查最大的字段中
maxNumber(可选)指定封顶集合允许在文件的最大数量,当插入文档,MongoDB 第一检查大小字段封顶集合,然后它会检查最大的字段中
// 首先切换到操作的数据库
use obeta

// 不使用选项的方法创建集合
db.createCollection('mycollection')

// 使用选项的方法创建集合
db.createCollection('mycol', {
  capped : false,
  autoIndexID : true,
  size : 6142800,
  max : 10000
})

// 查看集合
show collections

注意:有时候我们不需要特意去创建集合,当插入一些文件 MongoDB 自动创建的集合.下面语句会创建 collect 集合

db.collect.insert({
	name: 'obeta',
});

删除集合

MongoDB 的 db.collection.drop() 是用来从数据库中删除一个集合.

// 首先选定数据库
use obeta

// 查看所有的集合
show collections

// 删除创建的集合mycol
db.mycol.drop()

// 检查集合会发现集合mycol被删除了
show collections

插入文档

插入数据到 MongoDB 集合,需要使用 MongoDB 的 insert()save() 方法.

  • insert 语法:db.COLLECTION_NAME.insert(document)
  • save 语法:db.post.save(document)
// 插入数据
db.mycol.insert({
	name: 'obeta',
});
  • 这里 mycol 是集合的名称,如前面的教程中创建.
  • 如果集合在数据库中不存在,
  • 那么 MongoDB 将创建此集合,然后把它插入文档,如果我们不指定_id 参数,然后 MongoDB 本文档分配一个独特的 ObjectId.

2.查询文档

find() 方法.

// 查询当前数据库集合中的所有文档
db.mycol.find();

// 可以加pretty()来格式化输出
db.mycol.find().pretty();

// 查找指定的文档:name等于obeta的所有文档
db.mycol.find({
	name: 'obeta',
});

// 查找单个文档:name等于obeta的第一个文档
db.mycol.find({
	name: 'obeta',
});
  • 定制查询后返回显示的字段,而不是所有字段(投影)
  • 语法:db.COLLECTION_NAME.find({},{KEY:1}),第一个{}代表查询匹配的字段,第二个{}代表需要显示的字段,
  • 要限制返回字段,需要设置的字段列表值 1 或 0,1 代表返回,0 代表不返回.
// 查找所有字段,返回title的值和隐藏_id字段.

db.mycol.find(
	{},
	{
		title: 1,
		_id: 0,
	}
);

$操作符

操作符是 mongodb 里面很重要的一部分,很多复杂查询依赖于这些操作符.

比较操作符

下面我们将配合查询操作符来执行复杂的查询操作,比如元素查询、 逻辑查询 、比较查询操作.我们使用下面的比较操作符$gt$gte$lt$lte, $ne, $eq(分别对应>, >=, <, <=, !=, ==)

// $gt 查询年龄大于20的集合
db.COLLECTION_NAME.find({
	age: {
		$gt: 20,
	},
});

// $gte 查询年龄大于等于20的集合
db.COLLECTION_NAME.find({
	age: {
		$gte: 20,
	},
});

// $lt 查询年龄小于20的集合
db.COLLECTION_NAME.find({
	age: {
		$lt: 20,
	},
});

// $lte 查询年龄小于等于20的集合
db.COLLECTION_NAME.find({
	age: {
		$lte: 20,
	},
});

// $ne 查询年龄不等于20的集合
db.COLLECTION_NAME.find({
	age: {
		$ne: 20,
	},
});

// $eq 等于 db.COLLECTION_NAME.find({'name': 'obeta'})
db.COLLECTION_NAME.find({
	name: {
		$eq: 'obeta',
	},
});

比较操作符其中还有这两个$in, $nin:

  1. $in

匹配键值等于指定数组中任意值的文档.类似 sql 中 in,只要匹配一个 value 就会输出

语法: {field: { $in: [<value1>, <value2>, ... <valueN> ] }}

db.COLLECTION_NAME.find({
	age: {
		$in: [22, 33],
	},
});
// 年龄属于22,33
  1. $nin

匹配键不存在或者键值不等于指定数组的任意值的文档.类似 sql 中 not in(SQL 中字段不存在使用会有语法错误).

语法: find({field:{ $nin:[value, value1] }})

db.COLLECTION_NAME.find({
	age: {
		$nin: [100, 44],
	},
});
// 年龄不属于100,44

逻辑操作符

  1. $and

指定一个至少包含两个表达式的数组,选择出满足该数组中所有表达式的文档.$and 操作符使用短路操作,若第一个表达式的值为“false”,余下的表达式将不会执行.

语法: {$and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ]}

db.COLLECTION_NAME.find({
	$and: [
		{
			age: { $gt: 20 },
		},
		{
			age: { $lt: 30 },
		},
	],
});
// 年龄大于20和小于30
  1. $or

执行逻辑 OR 运算,指定一个至少包含两个表达式的数组,选择出至少满足数组中一条表达式的文档.

语法:find{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }

db.COLLECTION_NAME.find({
	$or: [{ age: 22 }, { age: 33 }],
});
// 年龄等于22或33
  1. $not

执行逻辑 NOT 运算,选择出不能匹配表达式的文档,包括没有指定键的文档.$not 操作符不能独立使用,必须跟其他操作一起使用.

语法: `find({ field: { $not: { [OTHERFEILD]: [OHTER_VALUE] } } })`_

db.COLLECTION_NAME.find({
	age: {
		$not: {
			$gt: 30,
		},
	},
});
// 查找不大于30的年龄
  1. $nor

查询与任一表达式都不匹配的文档.$nor 操作符不能独立使用,必须跟其他操作一起使用.

语法: `find({ field: { $nor: { [OTHERFEILD]: [OHTER_VALUE] } } })`_

db.COLLECTION_NAME.find({
	age: {
		$nor: {
			$gt: 30,
			$in: [25, 26],
		},
	},
});
// 查找小于30并不等于25,26的年龄

元素操作符

  1. $exists

如果$exists 的值为 true(或者 1),选择存在该字段的文档,若值为 false(或者 0)则选择不包含该字段的文档

db.COLLECTION_NAME.find({
	sex: {
		$exists: false,
	},
});
// 不存在有sex属性
  1. $type

$type 操作符是基于 BSON 类型来检索集合中匹配的数据类型

mongodb-$type
mongodb-$type

db.COLLECTION_NAME.find({
	sex: {
		$type: 2,
	},
});

匹配操作符

  1. $mod

取模运算, 语法: find({ field: { $mod: [ 除数, 余数 ] } })

db.COLLECTION_NAME.find({
	sex: {
		$mod: [2, 0],
	},
});
  1. $regex

正则匹配

/**
{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }
**/
db.COLLECTION_NAME.find({
	sex: {
		$regex: /6[0-9]/,
	},
}); // 匹配60-69岁的人
  1. $where

把一个含有 JavaScript 表达式的字符串或者是整个 JavaScript 函数转换到查询系统中进行查询

db.COLLECTION_NAME.find({
	$where: 'this.age < 20',
});

db.COLLECTION_NAME.find({
	$where: function() {
		return this.age < 20;
	},
});
  1. $text

在字符串内容上执行文本检索的查询操作. 使用这个之前必须创建了 text index.

先创建针对需要检索的字段索引db.COLLECTION_NAME.createIndex( { name: "text", description: "text" } )

/**
$test: {
	$search: <string>,
	$language: <string>,
	$caseSensitive: <boolean>,
	$diacriticSensitive: <boolean>
}
**/

// 检索包含 "java", "coffee", "shop"中任一个
db.COLLECTION_NAME.find({ $text: { $search: 'java coffee shop' } });

// 精确索引 "java" 或者 "coffee shop"
db.COLLECTION_NAME.find({ $text: { $search: 'java "coffee shop"' } });

// 词语排除 包含"java", "shop" 当不包含"coffee"
db.COLLECTION_NAME.find({ $text: { $search: 'java shop -coffee' } });

更多的信息可以点击这里

数组操作符

  1. $all

匹配文档的数组字段中包含所有指定元素的文档.

db.COLLECTION_NAME.find({
	field_is_array: [1, 2],
});
  1. $elemMatch

对数组中元素进行匹配.

// 有数据
// {field_is_array: [1, 5, 23, 27, 30, 35]}
// {field_is_array: [30, 35, 45]}
db.COLLECTION_NAME.find({
	field_is_array: {
		$elemMatch: {
			$gt: 20,
			$lt: 30,
		},
	},
}); // 匹配到第一条数据
  1. $size

匹配指定大小的数组.

db.COLLECTION_NAME.find({
	field_is_array: {
		$size: 5,
	},
});

限定操作符

查找的数据有时候本身就有很多其他数据,需要做限定返回结果,因此有以下这些操作符可以做限制.

  1. $slice

用来限制返回字段里的数组长度, 语法是find( { field: value }, { field_is_array: {$slice: count }}).

db.COLLECTION_NAME.find(
	{ field: value },
	{
		field_is_array: {
			$slice: count,
		},
	}
);

/**
只显示前5个: db.posts.find( {}, { comments: { $slice: 5 } } )  
只显示后5个: db.posts.find( {}, { comments: { $slice: -5 } } )  
跳过(skip)前20个,并只显示(limit)10个元素(即21-30):  db.posts.find( {}, { comments: { $slice: [ 20, 10 ] } } )  
跳过后20个,并显示10个: db.posts.find( {}, { comments: { $slice: [ -20, 10 ] } } ) 
**/
  1. $()

查找数组中收割匹配的元素.

// { field_array: [1, 49, 20] }
// { field_array: [16, 20, 50] }
db.COLLECTION_NAME.find(
	{
		field_array: {
			$lt: 20,
		},
	},
	{
		'field_array.$': 1,
	}
); // 'field_array'数组中的第一个
// 返回: [{ field_array: [1] }, { field_array: [16] }]
  1. $elemMatch

也是匹配数组中元素,并返回匹配的第一个元素.

// { age: 20, field_array: [{name: 'y'}, {name: 'z'}, {name: 'x}] }
db.COLLECTION_NAME.find(
	{
		age: 20,
	},
	{
		field_array: {
			$elemMatch: {
				name: 'z',
			},
		},
	}
);
// 返回: { age: 20, field_array: [{name: 'z'}] }
  1. $sample

随机获取文档中指定数量的数据.这是 aggregaion 中的操作.

db.COLLECTION_NAME.aggregation({ $sample: { size: 3 } }); // 随机获取3个数据

更新操作符

  1. $inc

字段自增或自减相应的数字

// 年龄为20的增加1
db.COLLECTION_NAME.update(
	{
		age: 20,
	},
	{
		$inc: {
			age: 1,
		},
	}
);
  1. $mul

字段与 value 相乘.

// 年龄为20的乘以2
db.COLLECTION_NAME.update(
	{
		age: 20,
	},
	{
		$mul: {
			age: 2,
		},
	}
);
  1. $rename

重命名字段

// 年龄大于20岁的将school改为work
db.COLLECTION_NAME.update(
	{
		age: {
			$gt: 20,
		},
	},
	{
		$rename: {
			school: 'work',
		},
	}
);
  1. $set

给字段设置值

// 年龄大于20岁的设置work
db.COLLECTION_NAME.update(
	{
		age: {
			$gt: 20,
		},
	},
	{
		$set: {
			work: 'no',
		},
	}
);
  1. $setOnInsert

配合 upsert 操作,在作为 insert 时可以为新文档扩展更多的 field,有时候 update 操作的时候并没有这条数据,加上{upsert: true}说明没有就插入这条数据,这时候这个设置就会被用上.

db.COLLECTION_NAME.update(
	{
		name: 'obeta',
	},
	{
		$set: {
			work: 'no',
		},
		$setOnInsert: {
			age: '24',
		},
	},
	{
		upsert: true,
	}
); // 有名字为obeta的时候设置work为no, 没有的时候会另外设置年龄为24
  1. $unset

删除字段,不存在则不操作

db.COLLECTION_NAME.update(
	{
		age: {
			$lt: 20,
		},
	},
	{
		$unset: {
			work: '',
		},
	}
);
  1. $min

当给定的值小于数据库里的值则更新此字段

// {name: 'obeta', age: 24}
db.COLLECTION_NAME.update(
	{
		name: 'obeta',
	},
	{
		$min: {
			age: 20,
		},
	}
);
  1. $max

当给定值大于数据库里的值则更新

// {name: 'obeta', age: 20}
db.COLLECTION_NAME.update(
	{
		name: 'obeta',
	},
	{
		$max: {
			age: 26,
		},
	}
);

更新文档

update()方法更新现有文档值.

// 将标题'MongoDB'的文档更新其标题是'New MongoDB'

db.mycol.update({ title: 'MongoDB' }, { $set: { title: 'New MongoDB' } });

默认只更新一个文件,如果要更新全部匹配的需要加 multi.

db.mycol.update(
  {'title':'MongoDB'},
  {$set:{'title':'New MongoDB'},
  {multi:true}
})

删除文档

remove() 方法.

// 将标题'MongoDB'的文档删除
db.mycol.remove({
	title: 'MongoDB',
});

// 删除所有匹配的
db.mycol.remove(
	{
		title: 'MongoDB',
	},
	true
);

// 删除集合所有文档
db.mycol.remove();

其它操作

  • limit()

限制 MongoDB 中的记录,需要使用 limit() 方法. limit() 方法接受一个数字型的参数,这是要显示的文档数.

// 返回指定数量的文档(这里返回2个)
db.mycol
	.find(
		{},
		{
			title: 'obeta',
		}
	)
	.limit(2);
  • skip()

除了 limit() 方法,还有一个方法 skip() 也接受数字类型的参数,并使用跳过的文档数.

// 只显示第二个文档.
db.mycol
	.find(
		{},
		{
			title: 'obeta',
		}
	)
	.limit(1)
	.skip(1);

通常我们使用这两个配合来进行分页返回数据.

  • sort()

要在 MongoDB 中的文档进行排序,需要使用 sort() 方法.

sort() 方法接受一个文档,其中包含的字段列表连同他们的排序顺序. 要指定排序顺序 1 和-1.1 用于升序排列,而-1 用于降序.

// 显示按标题降序排序的文件.
db.mycol.find({}, { title: 1, _id: 0 }).sort({ title: -1 });
  • count()

返回文档的个数.

db.mycol
	.find(
		{},
		{
			title: 'obeta',
		}
	)
	.count();

如果不指定排序优先,sort() 方法将文档显示为升序排列.


本教程仅供参考学习,如果阅读中有问题可以发邮件给我.最后,谢谢阅读.

个人随笔记录,内容不保证完全正确,若需要转载,请注明作者和出处.