MongoDB 3.4.2 SQL 查詢語句詳解

    本文對 MongoDB 的一些基本操做作一下整理和總結。 首先會介紹一下基於命令行的sql操做,其次結合 spring 的 mongoTemplate 介紹一下如何經過 java 操做數據庫。對 NoSQL 不熟悉的同窗能夠了解一下。html

1.版本

MongoDB 3.4.2java

2.安裝

安裝 MongoDB 能夠查看個人另一篇文章 CentOs7 急速安裝 MongoDBmysql

3.建立用戶

關於用戶建立和維護能夠查看個人另一遍文章 MongoDB 3.4.7 用戶基本操做web

4.命令行CRUD操做

這以 testUser 這個集合爲例子,下面的操做都是基於這個集合。spring

4.0 示例

下面分享2個別人的教程,一個是官網的例子,一個是菜鳥教程。若是看個人內容有疑惑的話能夠參考這2個教程。sql

官網示例(英文) 菜鳥教程(中文)mongodb

4.1 插入

語法格式:數據庫

db.COLLECTION_NAME.insert(document)

例子:bash

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

4.2 更新

語法格式:app

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

相關文章
相關標籤/搜索