MongoDB 教程三: 高级查询 (SQL到MongoDB映射表)

MongoDB 系列教程索引 : MongoDB 教程索引 (附有视频)

查询接口

对于查询操作,MongoDB 提供了 db.collection.find() 方法。这个方法接收查询条件和映射两个条件并且返回一个指向匹配文档的 游标 。你可以使用 limits, skip 和 sort orders 来有选择的修饰查询。

下图把 MongoDB 查询操作组成部分进行了高亮显示:

The components of a MongoDB find operation.

The components of a MongoDB find operation.

下图展示了使用 SQL 的相同查询:

The components of a SQL SELECT statement.

The components of a SQL SELECT statement.

例子

db.users.find( { age: { $gt: 18 } }, { name: 1, address: 1 } ).limit(5)

这查询从 user 集合中选择符合条件 age 大于 18 的文档。为了指定大于条件,查询条件使用大于(也就是 $gtquery selection operator 。这个查询最多返回 5 个匹配的文档(或者更准确的说,一个指向这些文档的游标)。这些匹配的文档将仅仅返回 _idnameaddress 字段。详细信息,请参阅 映射

针对以下图表,你可能会考虑查看 Frequently Asked Questions 章节查询一些关于MongoDB的常用问题。

术语和概念

下表中列出了多个SQL中的术语和概念以及相对应的MongoDB中的术语和概念。

SQL 术语/概念

MongoDB 术语/概念

数据库

数据库

集合

文档 or BSON 文档

字段

索引

索引

表连接

内嵌文档和

主键

指定任何唯一列或复合列作为主键。

主键

在MongoDB里,主键会自动设置为 _id 列。

聚合(e.g. group by)

聚合管道

查看文档 SQL to Aggregation Mapping Chart

可执行文件

下表中列出了一些数据库的可执行文件名以及相对应的MongoDB的可执行文件名。表中的数据并不是详尽的。

MongoDB MySQL Oracle Informix DB2
Database Server mongod

mysqld

oracle IDS DB2 Server
Database Client mongo mysql sqlplus DB-Access DB2 Client

示例

下表中列出了多种SQL语句以及相对应的MongoDB的语句。表中的示例有以下假设条件:

  • SQL示例假设在一个名叫“users“的表上执行。

  • MongoDB示例假设在一个名叫“users“的集合上执行,并且包含一些文档,这些文档有如下属性:

    {
      _id: ObjectId("509a8fb2f3f4948bd2f983a0"),
      user_id: "abc123",
      age: 55,
      status: 'A'
    }
    

创建和修改

下表中列出了多种表级别操作的SQL语句以及相对应的MongoDB的语句。

SQL 建模语句

MongoDB 建模语句

CREATE TABLE users (
    id MEDIUMINT NOT NULL
        AUTO_INCREMENT,
    user_id Varchar(30),
    age Number,
    status char(1),
    PRIMARY KEY (id)
)

第一次执行 insert() 操作时隐式创建。如果文档中不指定“_id“列,那么会自动添加“_id“列并默认为主键。

db.users.insert( {
    user_id: "abc123",
    age: 55,
    status: "A"
 } )

当然,你也可以显式的创建一个集合:

db.createCollection("users")
ALTER TABLE users
ADD join_date DATETIME

集合中并不强制规定文档的结构;比如:集合级别并没有文档结构转换的语句。

然而,在文档级别,可以使用 :method:`~db.collection.update()`方法中的 :update:`$set`操作符添加新的字段到现有的文档中。

db.users.update(
    { },
    { $set: { join_date: new Date() } },
    { multi: true }
)
ALTER TABLE users
DROP COLUMN join_date

集合中并不强制规定文档的结构;比如:集合级别并没有文档结构转换的语句。

然而,在文档级别,可以使用 update()`方法中的:update:`$unset 操作符从现有文档中删除一个字段。

db.users.update(
    { },
    { $unset: { join_date: "" } },
    { multi: true }
)
CREATE INDEX idx_user_id_asc
ON users(user_id)
db.users.ensureIndex( { user_id: 1 } )
CREATE INDEX
       idx_user_id_asc_age_desc
ON users(user_id, age DESC)
db.users.ensureIndex( { user_id: 1, age: -1 } )
DROP TABLE users
db.users.drop()

获取更多信息,查看 db.collection.insert(), db.createCollection(), db.collection.update(), $set, $unset, db.collection.ensureIndex(), indexes, db.collection.drop(), and 数据建模理论.

插入

下表中列出了多种关于插入操作的SQL语句以及相对应的MongoDB语句。

SQL 插入语句

Mongodb insert() 语句

INSERT INTO users(user_id,
                  age,
                  status)
VALUES ("bcd001",
        45,
        "A")
db.users.insert(
   { user_id: "bcd001", age: 45, status: "A" }
)

获取更多信息,查看 db.collection.insert().

查询

下表中列出了多种关于查询操作的SQL语句以及相对应的MongoDB语句。

SQL 查询语句

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( { user_id: /bc/ } )
SELECT *
FROM users
WHERE user_id like "bc%"
db.users.find( { user_id: /^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( { user_id: { $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.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()

获取更多信息,查看 db.collection.find(), db.collection.distinct(), db.collection.findOne(), $ne $and, $or, $gt, $lt, $exists, $lte, $regex, limit(), skip(), explain(), sort(), and count().

更新

下表中列出了多种关于更新的SQL语句以及相对应的MongoDB语句。

SQL 更新语句

MongoDB update() 语句

UPDATE users
SET status = "C"
WHERE age > 25
db.users.update(
   { age: { $gt: 25 } },
   { $set: { status: "C" } },
   { multi: true }
)
UPDATE users
SET age = age + 3
WHERE status = "A"
db.users.update(
   { status: "A" } ,
   { $inc: { age: 3 } },
   { multi: true }
)

获取更多信息,查看 db.collection.update(), $set, $inc, and $gt.

删除

下表中列出了多种关于删除的SQL语句以及相关的MongoDB语句。

SQL 删除语句

MongoDB remove() 语句

DELETE FROM users
WHERE status = "D"
db.users.remove( { status: "D" } )
DELETE FROM users
db.users.remove({})

获取更多信息,查看 db.collection.remove().

 

更多参考:MongoDB 2.6 中文文档

 

MongoDB 系列教程索引 : MongoDB 教程索引 (附有视频)

上一篇:  MongoDB 教程三: 高级查询

下一篇: MongoDB 教程四: 高级更改操作

本文:MongoDB 教程三: 高级查询 (SQL到MongoDB映射表)

Loading

Add a Comment

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.