MongoDB 3.4.2 SQL 查询语句详解

    本文对 MongoDB 的一些基本操作做一下整理和总结。 首先会介绍一下基于命令行的sql操作,其次结合 spring 的 mongoTemplate 介绍一下如何通过 java 操作数据库。对 NoSQL 不熟悉的同学可以了解一下。

1.版本

MongoDB 3.4.2

2.安装

安装 MongoDB 可以查看我的另外一篇文章 CentOs7 急速安装 MongoDB

3.创建用户

关于用户创建和维护可以查看我的另外一遍文章 MongoDB 3.4.7 用户基本操作

4.命令行CRUD操作

这以 testUser 这个集合为例子,下面的操作都是基于这个集合。

4.0 示例

下面分享2个别人的教程,一个是官网的例子,一个是菜鸟教程。如果看我的内容有疑惑的话可以参考这2个教程。

官网示例(英文) 菜鸟教程(中文)

4.1 插入

语法格式:

db.COLLECTION_NAME.insert(document)

例子:

> db.getCollection('testUser').insert({
     name: 'a',
     description: 'user a',
     age: 15,
     zone: 'shanghai'
     })
WriteResult({ "nInserted" : 1 })
>

4.2 更新

语法格式:

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

例子:

查出 name 字段为 a 的记录,更新 zone 字段为 hangzhou

> db.getCollection('testUser').update({
     name: 'a'
     }, {
     $set: {
         zone: 'hangzhou'
         }
     })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

这里需要注意, update 一共提供5个参数

  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。

所以上面的例子update只会更新一条数据,如果需要更新多条,需要将第4个参数设置为true

db.getCollection('testUser').update({
     name: 'a'
     }, {
     $set: {
         zone: 'hangzhou'
         }
     }, false, true)

第3个参数 upsert 的意思是,如果根据条件查到记录了就更新该记录,如果没有查到记录就插入一条记录。

 

4.3 删除

语法:

db.collection.remove(
   <query>,
   <justOne>
)

例子:

移除 name 字段为 a 的记录

>db.getCollection('testUser').remove({
    name: 'a'
 })

4.4 查询

语法:

db.collection.find(query, projection)

例子:

查询 name 为 a 的记录

db.getCollection('testUser').find({
    name: 'a'
})

查询 name 为 a, age 大于 14 的记录

db.getCollection('testUser').find({
    name: 'a', age: {$gt: 14}
})

还有一些 in or nin gt lt gte 等 大家可以意会一下,实在悟不出来可以点击这里

 

4.5 排序

语法:

db.COLLECTION_NAME.find().sort({KEY:1})

例子:

查询 name 为 a, age 大于 14 的记录, 按age升序排序。1 为升序,-1 为降序

db.getCollection('testUser').find({
    name: 'a', age: {$gt: 14}
}).sort({age:1})

 

4.6 索引

语法:

db.COLLECTION_NAME.ensureIndex({KEY:1})

例子:

为 zone 字段添加升序索引,并且在后台执行

db.getCollection('testUser').ensureIndex({zone:1}, {background: true})

 

查看索引

db.getCollection('testUser').getIndexes()

 

5.命令行聚合操作

聚合操作语法就有点复杂了,结合mysql语法讲解一下

mysql

select zone, count(zone) from testUser group by zone

mongo

> db.getCollection('testUser').aggregate([{
     $group: {
         _id: "$zone",
         num_total: {
             $sum: 1
             }
         }
     }])

{ "_id" : "hangzhou", "num_total" : 1 }
{ "_id" : "guangzhou", "num_total" : 500000 }
{ "_id" : "beijing", "num_total" : 2800000 }
{ "_id" : "shanghai", "num_total" : 400001 }

可以看到我这一个表里面有300多万数据,这个聚合执行下来 4.6 秒,还是挺快的。

 

mysql

select zone, count(zone) from testUser where age <= 15 group by zone

mongo

> db.getCollection('testUser').aggregate([
     {
         $match: {
             age: {$lte: 15}
         }
     },
     {
         $group: {
             _id: "$zone",
             count: {
                 $sum: 1
                 }
             }
     }
 ]);

{ "_id" : "hangzhou", "count" : 1 }
{ "_id" : "guangzhou", "count" : 500000 }
{ "_id" : "beijing", "count" : 2800000 }
{ "_id" : "shanghai", "count" : 400001 }

 

mysql

select zone, avg(age), count(zone) from testUser where age <= 15 group by zone

mongo

> db.getCollection('testUser').aggregate([
     {
         $match: {
             age: {$lte: 15}
         }
     },
     {
         $group: {
             _id: "$zone",
             avg: {
                 $avg: '$age'
                 },
             count: {
                 $sum: 1
                 }
             }
     }
 ]);

{ "_id" : "hangzhou", "avg" : 15, "count" : 1 }
{ "_id" : "guangzhou", "avg" : 15, "count" : 500000 }
{ "_id" : "beijing", "avg" : 15, "count" : 2800000 }
{ "_id" : "shanghai", "avg" : 15, "count" : 400001 }

 

详细的讲解猛戳这里

 

6.命令行非交互式执行sql

/xxx/mongodb-osx-x86_64-3.4.2/bin/mongo <collection_name> -u<username> -p<password> --eval "db.getCollection('xxxx').find({})"

 

7.使用MongoTemplate操作数据库

7.1 插入

TestUser testUser = new TestUser();
testUser.setUserId(1);
testUser.setUsername("a");
testUser.setAge(15);
testUser.setZone("beijing");
mongoTemplate.save(testUser);

 

7.2 查询全部

List<TestUser> testUserList = mongoTemplate.find(new Query(), TestUser.class);

 

7.3 条件查询

Query query = new Query();
query.addCriteria(Criteria.where("zone").is("shanghai"));
List<TestUser> testUserList = mongoTemplate.find(query, TestUser.class);

 

7.4 更新一条

Query query = new Query();
query.addCriteria(Criteria.where("userId").is(1));
Update update = new Update();
update.set("age", 22);
mongoTemplate.updateFirst(query, update, TestUser.class);

 

7.5 更新插入

Query query = new Query();
query.addCriteria(Criteria.where("userId").is(1));
Update update = new Update();
update.set("age", 22);
mongoTemplate.upsert(query, update, TestUser.class);

 

7.6 更新多条

Query query = new Query();
query.addCriteria(Criteria.where("userId").is(1));
Update update = new Update();
update.set("age", 22);
mongoTemplate.updateMulti(query, update, TestUser.class);

 

7.7 带条件聚合

Aggregation aggregation = newAggregation(
       match(Criteria.where("zone").is("guangzhou")),
       group().avg("age").as("avg_age").count().as("count")
);

AggregationResults<HashMap> aggregationResults = mongoTemplate.aggregate(aggregation, "testUser", HashMap.class);
List<HashMap> rs = aggregationResults.getMappedResults();

查询 zone 等于 guangzhou 的记录,按 zone 统计条数和平均年龄

 

7.8 无条件聚合

Aggregation aggregation = newAggregation(
      group("zone").count().as("count")
);

AggregationResults<HashMap> aggregationResults = mongoTemplate.aggregate(aggregation, "testUser", HashMap.class);
List<HashMap> rs = aggregationResults.getMappedResults();

按 zone 统计条数

 

7.9 删除

TestUser testUser = new TestUser();
testUser.setUserId(i);
testUser.setUsername("a");
testUser.setAge(15);
testUser.setZone("beijing");
mongoTemplate.remove(testUser);

 

8. 运行中异常

看到别人遇到过 groupby 产生的超出内存大小的限制,但是自己没有复现出来。就放2个地址记录下别人的经验。

http://www.codeweblog.com/mongodb-groupby%E6%93%8D%E4%BD%9C-%E7%BB%93%E6%9E%9C%E9%9B%86%E5%A4%A7%E5%B0%8F%E9%99%90%E5%88%B6%E9%97%AE%E9%A2%98/

https://www.cnblogs.com/viaiu/p/4848445.html

转载于:https://my.oschina.net/u/232911/blog/1818199

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值