Mongodb-CURD

Table of contents

  1. 一、查询入门
    1. 1、基础概念
    2. 2、入门示例
      1. 创建和修改
      2. 写入记录
      3. 查询/选择
      4. 更新记录
      5. 查询指定的列
      6. 删除记录
  2. 二、查询与映射运算符
    1. 1、常见函数
      1. (1)count()
      2. (2)distinct()
      3. (3)limit()
      4. (3)sort()
      5. (4)查特定列
    2. 2、查询选择器
      1. (1)比较
      2. (2)逻辑
      3. (3)元素
      4. (4)评估
      5. (5)数组
      6. (6)地理
      7. (7)按位运算
      8. (8)评论选
    3. 3、映射运算符

一、查询入门

1、基础概念

下表介绍了各种SQL术语和概念以及相应的MongoDB术语和概念。

SQL术语/概念 MongoDB术语/概念
database database
table collection
row document or BSON document
column field
index index
table joins $lookup, 嵌入文档
primary key (指定任何唯一的列或列组合作为主键。) primary key (在MongoDB中,主键自动设置为_id字段。)

MySQL中的许多概念在MongoDB中具有相近的类比。

MySQL MongoDB
库 database 库 database
表 table 集合 collection
行 row 文档 document 或 bson 文档
列 column 字段 field
表连接 joins 嵌入文档或链接
索引 index 索引 index
主键 可以自定义 主键 _id

数据库对于的服务也是类似的:

下表展示了一些数据库可执行文件和相应的MongoDB可执行文件。这个表格并不是详尽无遗的。

  MongoDB MySQL Oracle Informix DB2
Database Server mongod mysqld oracle IDS DB2 Server
Database Client mongo mysql sqlplus DB-Access DB2 Client

2、入门示例

下表展示了各种SQL语句和相应的MongoDB语句。表中的例子假设以下条件:

  • SQL示例假设有一个名为users的表。
  • MongoDB示例假设一个名为users的集合,它包含以下原型的文档:
{ 
       _id: ObjectId("509a8fb2f3f4948bd2f983a0"),
       user_id: "abc123",
       age: 55,
       status: 'A'
 }
创建和修改

下表展示了与表级操作相关的各种SQL语句以及相应的MongoDB语句。

SQL Schema语句 MongoDB Schema语句
CREATE TABLE users( id MEDIUMINT NOT NULL AUTO_INCREMENT, user_id Varchar(30), age Number, status char(1), PRIMARY KEY (id) ) 隐式创建的第一个insertOne()insertMany()操作。如果没有指定_id字段,则会自动添加主键_id。 db.users.insertOne( { user_id: “abc123”, age: 55, status: “A” } ) 但是,也可以显式地创建一个集合: db.createCollection(“users”)
ALTER TABLE users ADD join_date DATETIME 集合不描述或不强制其文件结构; 即在集合级别没有结构上的更改。 但是,在文档级别,updateMany()操作可以使用$set运算符将字段添加到现有文档中。 db.users.updateMany( { }, { $set: { join_date: new Date() } } )
ALTER TABLE users DROP COLUMN join_date 集合不描述或不强制其文件结构; 即在集合级别没有结构上的更改。 但是,在文档级别,updateMany()操作可以使用$unset运算符将字段添加到现有文档中。 db.users.updateMany( { }, { $unset: { “join_date”: “” } } )
CREATE INDEX idx_user_id_asc ON users(user_id) db.users.createIndex( { user_id: 1 } )
CREATE INDEX idx_user_id_asc_age_desc ON users(user_id, age DESC) db.users.createIndex( { user_id: 1, age: -1 } )
DROP TABLE users db.users.drop()
写入记录

下表显示了与将记录插入表和相应的MongoDB语句有关的各种SQL语句。

SQL INSERT语句 MongoDB insertOne() Statements
INSERT INTO users(user_id, age, status) VALUES (“bcd001”, 45, “A”) db.users.insertOne( { user_id: “bcd001”, age: 45, status: “A” } )

相关文档:

查询/选择

下表展示了与从表中读取记录相关的各种SQL语句以及相应的MongoDB语句。

注意

除非通过投影明确排除,否则[find()方法始终在返回的文档中包含_id字段。 下面的某些SQL查询可能包含一个_id字段来反映这一点,即使该字段未包含在相应的find()查询中也是如此。

SQL SELECT 语句 MongoDB find() 语句
SELECT FROM users db.users.find()
SELECT id, user_id, status FROM users db.users.find( { }, { user_id: 1, status: 1 } )
SELECT user_id, status FROM users db.users.find( { }, { user_id: 1, status: 1, _id: 0 } )
SELECT * FROM **users **WHERE status = “A” db.users.find( { status: “A” } )
SELECT user_id, status FROM users WHERE status = “A” db.users.find( { status: “A” }, { user_id: 1, status: 1, _id: 0 } )
SELECT * FROM users WHERE status != “A” db.users.find( { status: { $ne: “A” } } )
SELECT * FROM users WHERE status = “A” AND age = 50 db.users.find( { status: “A”, age: 50 } )
SELECT * FROM users WHERE status = “A” OR age = 50 db.users.find( { $or: [ { status: “A” } , { age: 50 } ] } )
SELECT * FROM users WHERE age > 25 db.users.find( { age: { $gt: 25 } } )
SELECT * FROM users WHERE age < 25 db.users.find( { age: { $lt: 25 } } )
SELECT * FROM users WHERE age > 25 AND age <= 50 db.users.find( { age: { $gt: 25, $lte: 50 } } )
SELECT * FROM users WHERE user_id like “%bc%” db.users.find( { userid: /bc/ } ) _or db.users.find( { user_id: { $regex: /bc/ } } )
SELECT * FROM users WHERE user_id like “bc%” db.users.find( { userid: /^bc/ } ) _or db.users.find( { user_id: { $regex: /^bc/ } } )
SELECT * FROM users WHERE status = “A” ORDER BY user_id ASC db.users.find( { status: “A” } ).sort( { user_id: 1 } )
SELECT * FROM users WHERE status = “A” ORDER BY user_id DESC db.users.find( { status: “A” } ).sort( { user_id: -1 } )
SELECT COUNT(*) FROM users db.users.count() or db.users.find().count()
SELECT COUNT(user_id) FROM users db.users.count( { userid: { $exists: true } } ) _or db.users.find( { user_id: { $exists: true } } ).count()
SELECT COUNT() FROM users WHERE age > 30 db.users.count( { age: { $gt: 30 } } ) or db.users.find( { age: { $gt: 30 } } ).count()
SELECT DISTINCT(status) FROM users db.users.aggregate( [ { $group : { _id : “$status” } } ] ) or, for distinct value sets that do not exceed the BSON size limit db.users.distinct( “status” )
SELECT * FROM users LIMIT 1 db.users.findOne() or db.users.find().limit(1)
SELECT * FROM users LIMIT 5 SKIP 10 db.users.find().limit(5).skip(10)
EXPLAIN SELECT FROM users WHERE status = “A” db.users.find( { status: “A” } ).explain()

相关文档:

更新记录

下表显示了与更新表中的现有记录和相应的MongoDB语句有关的各种SQL语句。

SQL Update Statements MongoDB updateMany() Statements
UPDATE users SET status = “C” WHERE age > 25 db.users.updateMany( { age: { $gt: 25 } }, { $set: { status: “C” } } )
UPDATE users SET age = age + 3 WHERE status = “A” db.users.updateMany( { status: “A” } , { $inc: { age: 3 } } )

相关文档:

查询指定的列

下表展示了与从表中读取记录相关的各种SQL语句以及相应的MongoDB语句。

注意

除非通过投影明确排除,否则[find()方法始终在返回的文档中包含_id字段。 下面的某些SQL查询可能包含一个_id字段来反映这一点,即使该字段未包含在相应的find()查询中也是如此。

SQL SELECT 语句 MongoDB find() 语句
SELECT * FROM users db.users.find()
SELECT id, user_id, status FROM users db.users.find( { }, { user_id: 1, status: 1 } )
SELECT user_id, status FROM users db.users.find( { }, { user_id: 1, status: 1, _id: 0 } )
SELECT * FROM users WHERE status = “A” db.users.find( { status: “A” } )
SELECT user_id, status FROM users WHERE status = “A” db.users.find( { status: “A” }, { user_id: 1, status: 1, _id: 0 } )
SELECT * FROM users WHERE status != “A” db.users.find( { status: { $ne: “A” } } )
SELECT * FROM users WHERE status = “A” AND age = 50 db.users.find( { status: “A”, age: 50 } )
SELECT * FROM users WHERE status = “A” OR age = 50 db.users.find( { $or: [ { status: “A” } , { age: 50 } ] } )
SELECT * FROM users WHERE age > 25 db.users.find( { age: { $gt: 25 } } )
SELECT * FROM users WHERE age < 25 db.users.find( { age: { $lt: 25 } } )
SELECT * FROM users WHERE age > 25 AND age <= 50 db.users.find( { age: { $gt: 25, $lte: 50 } } )
SELECT * FROM users WHERE user_id like “%bc%” db.users.find( { userid: /bc/ } ) _or db.users.find( { user_id: { $regex: /bc/ } } )
SELECT * FROM users WHERE user_id like “bc%” db.users.find( { userid: /^bc/ } ) _or db.users.find( { user_id: { $regex: /^bc/ } } )
SELECT * FROM users WHERE status = “A” ORDER BY user_id ASC db.users.find( { status: “A” } ).sort( { user_id: 1 } )
SELECT * FROM users WHERE status = “A” ORDER BY user_id DESC db.users.find( { status: “A” } ).sort( { user_id: -1 } )
SELECT COUNT(*) FROM users db.users.count() or db.users.find().count()
SELECT COUNT(user_id) FROM users db.users.count( { userid: { $exists: true*** *} } ) _or db.users.find( { user_id: { $exists: **true } } ).count()
SELECT COUNT ()* **FROM users WHERE age > 30 db.users.count( { age: { $gt: 30 } } ) or db.users.find( { age: { $gt: 30 } } ).count()
SELECT DISTINCT(status) FROM users db.users.aggregate( [ { $group : { _id : “$status” } } ] ) or, for distinct value sets that do not exceed the BSON size limit db.users.distinct( “status” )
SELECT * FROM users LIMIT 1 db.users.findOne() or db.users.find().limit(1)
SELECT * FROM users LIMIT 5 SKIP 10 db.users.find().limit(5).skip(10)
EXPLAIN SELECT * FROM users WHERE status = “A” db.users.find( { status: “A” } ).explain()

相关文档

删除记录

下表显示了与从表中删除记录和相应的MongoDB语句有关的各种SQL语句。

SQL Delete Statements MongoDB deleteMany() Statements
DELETE FROM users WHERE status = “D” db.users.deleteMany( { status: “D” } )
DELETE FROM users db.users.deleteMany({})

获得更多信息,请参见:db.collection.deleteMany().

另看:

二、查询与映射运算符

1、常见函数

(1)count()

统计条数。

select count(*) from users; 

db.users.count(); 

(2)distinct()

去重。

select distinct (name) from users; 

db.users.distinct('name');

####

(3)limit()

select * from users limit 10; 

db.users.find().limit(10););

(3)sort()

select * from users order by  opdate  desc; 

db.users.find()..sort({
"opdate":-1
});

排序函数,类似order by 1是升序,-1降序。

(4)查特定列

select name, skills from users;

db.users.find({}, {'name' : 1, 'age' : 1}); 

补充说明: 第一个{} 放where条件 第二个{} 指定那些列显示和不显示 (0表示不显示 1表示显示)

2、查询选择器

(1)比较

有关不同BSON类型值的比较,请参见指定的BSON比较顺序。

$eq

选择:等于某个值

{ <field>: { $eq: <value> } }

示例:

查询年龄等于18岁的用户:

db.Users.find({ age : {$eq:18} })

等价sql:

SELECT * FROM USERS WHERE age = 18;

$gt

选择:大于某个值

{field: {$gt: value} }

示例:

查询年龄大于18岁的用户:

db.Users.find({ age : {$gt:18} })

等价sql:

SELECT * FROM USERS WHERE age > 18;

$gte

选择:大于等于某个值

{field: {$gte: value} }

示例:

查询年龄大于或等于18岁的用户:

db.Users.find({ age : {$gte:18} })

等价sql:

SELECT * FROM USERS WHERE age >= 18;

$lt

选择:小于某个值

{field: {$lt: value} }

示例:

查询年龄小于22岁的用户:

db.Users.find({ age : {$lt:18} })

等价sql:

SELECT * FROM USERS WHERE age < 22;

$lte

选择:小于等于某个值

{ field: { $lte: value} }

示例:

查询年龄小于22岁的用户:

db.Users.find({ age : {$lte:22} })

等价sql:

SELECT * FROM USERS WHERE age <= 22;

$ne

{field: {$ne: value} }

选择:

field不等于某个值 field不存在

示例:

查询用户状态不等于1的用户

db.Users.find({ status : {$ne: 1} })

等价sql:

SELECT * FROM USERS WHERE status != 1;

$in

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

选择:

(1)filed是一个值,并且等于value1 or value2 。 (2)field是个数组,并且filed中至少存在某个值等于value1 or value2 。

示例:

查询指定邮箱的用户:

db.Users.find({ email : {$in: ['small-rose@qq.com','xiaocai@qq.com']} })

等价SQL:

SELECT * FROM USERS WHERE email in ('small-rose@qq.com','xiaocai@qq.com');

$nin

{ field: { $nin: [ <value1>, <value2> ... <valueN> ]} }

选择: (1)field值不存在于数组中 (2)field不存在

示例:

查询不含有某几个邮箱的用户:

db.Users.find({ email : {$nin: ['small-rose@qq.com','xiaocai@qq.com']} })

等价SQL:

SELECT * FROM USERS WHERE email NOT IN ('small-rose@qq.com','xiaocai@qq.com');

(2)逻辑

$and

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

含义:选择同时匹配所有expression的数据,如果expression1为false,则mongodb不会继续后续的判断

示例:

查询年龄是20,状态为1的用户:

db.Users.find({ $and : [ { age : 20}, { status : 1} ]});

如果找不到年龄为20的,status为1不作判断。

等价SQL:

SELECT * FROM USERS WHERE age =20 and status =1;

$not

{ field: { $not: { <operator-expression> } } }

含义:选择所有不符合operator-expression的数据。

示例:

查询所有状态不为1 或者status字段不存在的用户:

db.Users.find({ $not : [{ status : 1} ]});

等价SQL:

SELECT * FROM USERS WHERE status !=1;

$or

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

含义:选择至少满足一个expression的数据。

示例:

查询所有状态为1或者状态为3的用户:

db.Users.find({ $or : [{ status : 1},{ status : 3} ]});

等价SQL:

SELECT * FROM USERS WHERE status =1 or status =3 ;

$nor

{ $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] }

含义:选择同时不满足所有expression的数据。

示例:

查询所有状态为1或者状态为3的用户:

db.Users.find({ $or : [{ status : 1},{ status : 3},{ age : 22} ]});

等价SQL:

SELECT * FROM USERS WHERE status =1 or status =3 or age = 22;

(3)元素

$exists

{ field: { $exists: <boolean> } }

含义:选选择filed是否存在的数据,$exists: true代表存在,false代表不存在。

示例:

查询所有邮箱没有值的用户:

db.Users.find({ email: { $exists : false} });

等价SQL:

SELECT * FROM USERS WHERE email is null ;

$type

{ field: { $type: <BSON type> } }

含义:选择filed是某个具体类型的实例的数据,可以写具体type或者对应数字。

具体BSON type可以看文档:Bson Type

  选择字段值为指定的BSON数据类型的文档.使用下面类型对应的编号:

类型 类型 编号
Double 双精度 1
String 字符串 2
Object 对象 3
Array 数组 4
Binary data 二进制对象 5
Object id 对象id 7
Boolean 布尔值 8
Date 日期 9
Null 未定义 10
Regular Expression 正则表达式 11
JavaScript JavaScript代码 13
Symbol 符号 14
JavaScript (with scope) JavaScript代码(带范围) 15
32-bit integer 32 位整数 16
Timestamp 时间戳 17
64-bit integer 64 位整数 18
Min key 最小键 255
Max key 最大键 127

  如果文档的键值是一个数组。那么$type将对数组里面的元素进行类型匹配而不是键值数组本身。

示例:

{ "_id" : 1, "name" : "Jack", "age": 18, "tags": ['student','child'] }
{ "_id" : 2, "name" : "Lucy", "age": 22, "tags": ['teacher','foods'] }
{ "_id" : 2, "name" : "Lucy", "age": 22, "tags": 'teacher' }
{ "_id" : 2, "name" : "Lucy", "age": 22 }

查询所有标签的数据类型是数组的的用户:

db.user.find( { tags: { $type : 4 } } )

//如果想检查键值的类型是否为数组类型,使用$where操作符
db.user.find( { $where : "Array.isArray(this.tags)" } )

(4)评估

$expr

{ $expr: { <expression> } }

含义:选择filed符合聚合表达式的数据。

聚合表达式官方参考:聚合表达式管道参考

示例:

查询所有spent值大于budget值的所有数据:

数据:

{ "_id" : 1, "category" : "food", "budget": 400, "spent": 450 }
{ "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 }
{ "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 }
{ "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 }
{ "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }

查询语句

db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )

结果:

{ "_id" : 1, "category" : "food", "budget" : 400, "spent" : 450 }
{ "_id" : 2, "category" : "drinks", "budget" : 100, "spent" : 150 }
{ "_id" : 5, "category" : "travel", "budget" : 200, "spent" : 650 }

等价伪SQL:

SELECT * FROM monthlyBudget WHERE spent > budget ;
Name Description
$expr 允许在查询语言中使用聚合表达式。
$jsonSchema 根据给定的JSON Schema验证文档。
$mod 对字段的值执行模运算并选择具有指定结果的文档。
$regex 选择值与指定的正则表达式匹配的文档。
$text 执行文本搜索。
$where 匹配满足JavaScript表达式的文档。

(5)数组

注意

有关特定运算符的详细信息,包括语法和示例,请单击特定运算符以转到其参考页。

名称 描述
$all 匹配包含查询中指定的所有元素的数组。
$elemMatch 如果array字段中的元素符合所有指定$elemMatch条件,则选择文档。
$size 如果数组字段为指定大小,则选择文档。

示例:

{ "_id" : 1, "name" : "Jack", "age": 18, "tags": ['student','child'] }
{ "_id" : 2, "name" : "Lucy", "age": 22, "tags": ['teacher','foods'] }
{ "_id" : 2, "name" : "Lucy", "age": 22, "tags": ['python','mysql','java'] }
{ "_id" : 2, "name" : "Lucy", "age": 21, "tags": ['java','python']  }

查询所有标签的数据类型是数组的的用户:

//tags 中必须同时包含java 和 python 
db.users.find({'tags' : {'$all' : ['java','python']}})

//tags数组长度为3的数据,注意 $size不能与$lt等组合使用
db.users.find({'tags' : {'$size' : 3}}) 

(6)地理

6.1 查询选择器

Name Description
$geoIntersects 选择与GeoJSON几何形状相交的几何形状。2dsphere索引支持 $geoIntersects
$geoWithin 选择边界GeoJSON几何内的几何。2dsphere和2D指标支持 $geoWithin
$near 返回点附近的地理空间对象。需要地理空间索引。2dsphere和2D指标支持 $near
$nearSphere 返回球体上某个点附近的地理空间对象。需要地理空间索引。2dsphere和2D指标支持 $nearSphere

6.2 几何说明符

名称 描述
$box 使用传统坐标对来指定一个矩形框进行 $geoWithin查询。所述2D指数支持 $box
$center 使用平面几何时,使用旧坐标对指定圆以进行$geoWithin查询。所述2D指数支持$center
$centerSphere 使用球形几何图形时,使用传统坐标对或GeoJSON格式指定一个圆 用于$geoWithin查询。2dsphere和 2D指标支持$centerSphere
$geometry 为地理空间查询运算符指定GeoJSON格式的几何。
$maxDistance 指定最大距离以限制$near$nearSphere查询的结果。2dsphere和2D指标支持 $maxDistance
$minDistance 指定最小距离以限制$near$nearSphere查询的结果。2dsphere仅用于索引。
$polygon 指定用于$geoWithin查询的旧坐标对的多边形。2d索引支持$center
$uniqueDocs 不推荐使用。修改$geoWithin$near查询以确保即使文档多次匹配查询,查询也只返回一次文档。

(7)按位运算

注意

有关特定运算符的详细信息,包括语法和示例,请单击特定运算符以转到其参考页。

名称 描述
$bitsAllClear 匹配数字或二进制值,其中一组位的所有值均为0
$bitsAllSet 匹配数字或二进制值,其中一组位的所有值均为1
$bitsAnyClear 匹配数值或二进制值,在这些数值或二进制值中,一组位的位置中任何位的值为0
$bitsAnySet 匹配数值或二进制值,在这些数值或二进制值中,一组位的位置中任何位的值为1

(8)评论选

Name Description
$comment Adds a comment to a query predicate.

3、映射运算符

Name Description
$ 匹配数组中与查询条件匹配的第一个元素。
$elemMatch Projects the first element in an array that matches the specified $elemMatch condition.
$meta Projects the document’s score assigned during $text operation.
$slice Limits the number of elements projected from an array. Supports skip and limit slices.

参考资料:

https://mongoing.com/docs/core/query-plans.html

https://mongoing.com/archives/docs/mongodb

https://docs.mongodb.com/v4.0/reference/operator/query/

##