MongoDB 3.4.2 基本操作

    本文对 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>
   }
)

例子:

扫描二维码关注公众号,回复: 1010683 查看本文章

查出 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);

猜你喜欢

转载自my.oschina.net/u/232911/blog/1818199