Mongodb
中文文档:https://docs.mongoing.com/mongodb-crud-operations/insert-documents
命令文档:https://www.mongodb.com/docs/v4.2/reference/operator/query/
1、数据库
# 查看当前数据库
db
# 切换数据库,如果数据库不存在则自动创建
use <数据库名称>
# 删除当前 use 的数据库
db.dropDatabase()
# 数据备份
mongodump --db <database_name> --out <backup_directory>
2、集合
MongoDB将文档存储在集合中。集合类似于关系数据库中的表
创建集合
显式创建
db.createCollection( <name>, { // 创建一个有大小限制的集合 capped: <boolean>, // 是否自动为每个文档的_id字段创建索引 autoIndexId: <boolean>, // 有大小限制的集合的最大字节大小 size: <number>, // 有大小限制的集合中允许的最大文档数 max: <number>, // 存储引擎的配置选项 storageEngine: <document>, // 验证器,用于确保插入或更新的文档满足指定的条件 validator: <document>, // 验证器操作级别的选项:"moderate","strict",或 "ruthless" validationLevel: <string>, // 当文档不满足验证器条件时采取的操作:"error" 或 "warn" validationAction: <string>, // 索引选项的默认值 indexOptionDefaults: <document>, // 视图所基于的集合名称 viewOn: <string>, // 从数据到视图的转换过程 pipeline: <pipeline>, // 集合的排序规则 collation: <document>, // 写入关注点,即确认写操作完成之前所需满足的条件 writeConcern: <document> } )自动创建
db.myCollection2.insertOne( { x: 1 } )
文档验证
默认情况下,集合不要求其文档具有相同的模式。也就是说,单个集合中的文档不需要具有相同的字段集,并且字段的数据类型可以在集合中的不同文档之间有所不同。
但是,从MongoDB 3.2开始,您可以在更新和插入操作期间对集合强制执行文档验证规则。有关详细信息,请参见模式验证。
文档验证需要在创建文档的时候指定,如下:
db.createCollection("students", {
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "name", "year"],
properties: {
name: {
bsonType: "string",
description: "must be a string and is required"
} ,
year: {
bsonType: "int",
minimum: 2017,
maximum: 3017,
description: "must be an integer in [ 2017, 3017 ] and is required"
} ,
address: {
bsonType: "object",
required: [ "city" ],
properties: {
street: {
bsonType: "string",
description: "must be a string if the field exists"
} ,
city: {
bsonType: "string",
"description": "must be a string and is required"
}
}
}
}
}
}
} )
也可以使用如下方式创建
db.createCollection( "contacts",
{ validator: { $or:
[
{ phone: { $type: "string" } } ,
{ email: { $regex: /@mongodb\.com$/ } } ,
{ status: { $in: [ "Unknown", "Incomplete" ] } }
]
}
} )
3、文档
MongoDB文档由字段和值对组成,并具有以下结构:
var mydoc = {
_id: ObjectId("5099803df3f4948bd2f98391"),
name: { first: "Alan", last: "Turing" } ,
birth: new Date('Jun 23, 1912'),
death: new Date('Jun 07, 1954'),
contribs: [ "Turing machine", "Turing test", "Turingery" ],
views : NumberLong(1250000)
}
字段名称
字段名称
_id保留用作主键;它的值在集合中必须是唯一的,不可变的,并且可以是数组以外的任何类型。如果插入的文档省略了该_id字段,则MongoDB驱动程序会自动为该_id字段生成一个ObjectId。字段名称不能包含
null字符。顶级字段名称不能以美元符号(
$)字符开头。
数组
要通过从零开始的索引位置指定或访问数组的元素,请将数组名称与点(.)和从零开始的索引位置连接起来,并用引号引起来:
{
...
contribs: [ "Turing machine", "Turing test", "Turingery" ],
...
}
要指定contribs数组中的第三个元素,请使用点符号"contribs.2"
4、CRUD
文档插入
插入文档
db.inventory.insertOne(
{ item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)
插入多个文档
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } } ,
{ item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } } ,
{ item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])
文档查询
命令文档:https://www.mongodb.com/docs/v4.2/reference/operator/query/
查询所有
db.inventory.find( { } )
等值查询
db.inventory.find( { status: "D" } )
in 查询
db.inventory.find( { status: { $in: [ "A", "D" ] } } )
and 查询
db.inventory.find( { status: "A", qty: { $lt: 30 } } )
or 查询
db.inventory.find( { $or: [ { status: "A" } , { qty: { $lt: 30 } } ] } )
多条件查询
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } } , { item: /^p/ } ]
} )
查询数组
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] } ,
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] } ,
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] } ,
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] } ,
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);
查询完全等于的数组
db.inventory.find( { tags: ["red", "blank"] } )
查询包含内容的数组,不区分顺序
db.inventory.find( { tags: { $all: ["red", "blank"] } } )
# 等价于
db.inventory.find( { $and: [ { tags: "red" } , { tags: "blank" } ] } )
查询包含内容的数组
db.inventory.find( { tags: "red" } )
多条件查询
# 单个元素同时满足大于15并且小于20,或者一个元素满足大于15,另外一个元素小于20的所有文档
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
# 数组中最少一个元素同时满足所有的查询条件
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )
通过数组下标查询
# 数组字段dim_cm中第二个元素大于25的所有文档
db.inventory.find( { "dim_cm.1": { $gt: 25 } } )
通过数组长度查询
db.inventory.find( { "tags": { $size: 3 } } )
查询嵌套文档
db.inventory.insertMany( [
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" } , status: "A" } ,
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" } , status: "A" } ,
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" } , status: "D" } ,
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" } , status: "D" } ,
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" } , status: "A" }
]);
# 下面的案例返回inventory集合中size字段的值等于文档{ h: 14, w: 21, uom: "cm" } 的所有文档
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )
# 但如果调换了顺序则查询不到
db.inventory.find( { size: { w: 21, h: 14, uom: "cm" } } )
# 可以通过如下方式进行嵌套查询
db.inventory.find( { "size.uom": "in" } )
db.inventory.find( { "size.h": { $lt: 15 } } )
db.inventory.find( { "size.h": { $lt: 15 } , "size.uom": "in", status: "D" } )
更新文档
更新命令文档:https://www.mongodb.com/docs/upcoming/reference/operator/update/set/#up._S_set
db.inventory.insertMany( [
{ item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" } , status: "A" } ,
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" } , status: "A" } ,
{ item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" } , status: "A" } ,
{ item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" } , status: "P" } ,
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" } , status: "P" } ,
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" } , status: "D" } ,
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" } , status: "D" } ,
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" } , status: "A" } ,
{ item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" } , status: "A" } ,
{ item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" } , status: "A" }
] );
更新单个文档
db.inventory.updateOne(
{ item: "paper" } ,
{
$set: { "size.uom": "cm", status: "P" } ,
$currentDate: { lastModified: true }
}
)
- 使用$set 运算符将size.uom字段的值更新为“ cm”,将状态字段的值更新为“ P”
- 使用$currentDate运算符将lastModified字段的值更新为当前日期。 如果lastModified字段不存在,则$currentDate将创建该字段
更新多个文档
db.inventory.updateMany(
{ "qty": { $lt: 50 } } ,
{
$set: { "size.uom": "in", status: "P" } ,
$currentDate: { lastModified: true }
}
)
替换文档
db.inventory.replaceOne(
{ item: "paper" } ,
{ item: "paper", instock: [ { warehouse: "A", qty: 60 } , { warehouse: "B", qty: 40 } ] }
)
直接将 item 等于 paper 的文档内容替换成新的
删除文档
db.inventory.insertMany( [
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" } , status: "A" } ,
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" } , status: "P" } ,
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" } , status: "D" } ,
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" } , status: "D" } ,
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" } , status: "A" } ,
] );
删除所有文档
db.inventory.deleteMany({ } )
删除单个文档
db.inventory.deleteOne( { status: "D" } )
批量操作
- 有序操作:MongoDB串行地执行操作。 如果在某个单独的写操作的处理过程中发生错误,MongoDB将直接返回而不再继续处理列表中任何剩余的写操作
- 无序操作:MongoDB可以并行地执行操作,但是不能保证此行为。 如果某个单独的写操作的处理过程中发生错误,MongoDB将继续处理列表中剩余的写操作
bulkWrite()方法
bulkWrite() 支持如下操作:
- insertOne
- updateOne
- updateMany
- replaceOne
- deleteOne
- deleteMany
try {
db.characters.bulkWrite(
[
{ insertOne :
{
"document" :
{
"_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
}
}
} ,
{ insertOne :
{
"document" :
{
"_id" : 5, "char" : "Taeln", "class" : "fighter", "lvl" : 3
}
}
} ,
{ updateOne :
{
"filter" : { "char" : "Eldon" } ,
"update" : { $set : { "status" : "Critical Injury" } }
}
} ,
{ deleteOne :
{ "filter" : { "char" : "Brisbane"} }
} ,
{ replaceOne :
{
"filter" : { "char" : "Meldane" } ,
"replacement" : { "char" : "Tanys", "class" : "oracle", "lvl" : 4 }
}
}
]
);
}
catch (e) {
print(e);
}
该操作将返回如下的结果:
{
"acknowledged" : true,
"deletedCount" : 1,
"insertedCount" : 2,
"matchedCount" : 2,
"upsertedCount" : 0,
"insertedIds" : {
"0" : 4,
"1" : 5
} ,
"upsertedIds" : {
}
}
5、springboot集成
1、导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2、编写实体类
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "people")
public class Person {
@Id
private String id;
private String name;
private int age;
// 省略getter和setter方法
}
3、创建 mapper 接口
import org.springframework.data.mongodb.repository.MongoRepository;
public interface PersonRepository extends MongoRepository<Person, String> {
}
4、实现 crud
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonService {
@Autowired
private final PersonRepository personRepository;
public void savePerson(Person person) {
personRepository.save(person);
}
public void deletePerson(String id) {
personRepository.deleteById(id);
}
public Person findPersonById(String id) {
return personRepository.findById(id).orElse(null);
}
public List<Person> getAllPeople() {
return personRepository.findAll();
}
}
实现复杂查询
@Service
public class PersonService {
@Autowired
private MongoTemplate mongoTemplate;
public List<Person> findPeopleAgeGreaterThan18() {
Query query = new Query();
query.addCriteria(Criteria.where("age").gt(18).and("name").is("zhangsan"));
return mongoTemplate.find(query, Person.class);
}
}
也可以在接口中用注解查询
@Repository
public interface PersonRepository extends MongoRepository<Person, String> {
@Query("{ 'age': { $gt: ?0} } ")
List<Person> findByAgeGreaterThan(int age);
}
聚合管道
@Service
public class PersonService {
@Autowired
private MongoTemplate mongoTemplate;
public AggregationResults<Person> findPeopleByAgeRange(int minAge, int maxAge) {
AggregationOperation match = Aggregation.match(Criteria.where("age").gte(minAge).lte(maxAge));
AggregationOperation group = Aggregation.group("age").count().as("count");
Aggregation aggregation = Aggregation.newAggregation(match, group);
return mongoTemplate.aggregate(aggregation, Person.class);
}
}
- 本文链接:https://lxjblog.gitee.io/2023/12/27/mongodb/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。