1. 程式人生 > 資料庫 >MongoDB( 五 )MongoDB普通查詢和聚合查詢

MongoDB( 五 )MongoDB普通查詢和聚合查詢

目錄

 

 


一 : 普通操作

MongoDB的普通查詢MongoTemplate與Mysql的JdbcTemplate或者說是Redis的RedisTemplate別無二致 , 使用方式完全相同;

在使用之間建立一個臨時使用的test集合, 結構如下

db.getCollection("testDocuments").insert( {
    _id: ObjectId("5fe9439e66730000e70058d0"),
    name: "huang",
    age: 21,
    gender: "男"
} );
db.getCollection("testDocuments").insert( {
    _id: ObjectId("5fe943bb66730000e70058d1"),
    name: "lu",
    age: 26,
    gender: "男"
} );
db.getCollection("testDocuments").insert( {
    _id: ObjectId("5fe943cf66730000e70058d2"),
    name: "huang",
    age: 2,
    gender: "女"
} );

例項:

  • 插入文件

1 . 使用mongoTemplate直接插入自定義實體類

        MongoTestDTO mongoTestDTO = new MongoTestDTO();
        mongoTestDTO.setName("huangxiapkuan");
        mongoTestDTO.setAge("21");
        mongoTestDTO.setGender("男");
        mongoTemplate.insert(mongoTestDTO , "testDocuments");

 2 . 使用mongoTemplate插入Mongo自帶可動態擴充套件實體類Document.class

import org.bson.Document

// 批量插入 改為 insertMany(List<Document>) 即可
mongoTemplate.insert(new Document("name" , "zhang")
                .append("age" , "33").append("gender" , "男"), "testDocuments");

3 . MongoTemplate提供了官方客戶端驅動的封裝,官方客戶端有的方法,它都能呼叫  , 此外還提供了一種更統一的execute方法,

             它通過註冊一個回撥,來實現MongoDB操作以及資料回傳:

mongoTemplate.execute(mongodb -> {
            mongodb.getCollection("testDocuments").insertOne(new Document("name" , "isnert3")
                    .append("age" , "33").append("gender" , "男"));
            return "sucess";
        });

 4 . Mongo原生SQL如下: 

db.testDocuments.insert({
    name: 'huang',
    age: 2,
    gender: '男'
})

 

  •  刪除文件

1 .  使用mongoTemplate進行刪除操作 , 需要提供Query也就是條件   , 和集合名 , 注意以下使用的 remove()更換為 findAllAndRemove() 則為批量刪除

     刪除條件 name = ''insert3'' 的 資料

Query query =  new Query();
// Criteria 可自定義建立條件 
query.addCriteria(Criteria.where("name").is("insert3"));
mongoTemplate.remove(query , "testDocuments");

 刪除條件 _id = ''5feae0eb47801f7dfef1bf2d'' 的 資料

Query query =  new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feae0eb47801f7dfef1bf2d")));
mongoTemplate.remove(query , "testDocuments");

2 . 使用 MongoTemplate.execute 來執行回撥函式  ,用來進行刪除操作 , 官方客戶端有的方法,它都能呼叫

        mongoTemplate.execute( mongodb -> {
            mongodb.getCollection("testDocuments").deleteOne(new Document("name","isnert3"));
            return "sucess";
        });
        // 又或者
        mongoTemplate.execute("testDocuments" ,mongodb -> {
            mongodb.deleteOne(new Document("name","isnert3"));
            return "sucess";
        });

 3 . MongoDb原生SQL刪除語句如下

db.testDocuments.remove({
    'name': 'insert3'
})
  •  更新文件

1 . 使用MongoTemplate.upsert(Query  , Update , CollectionName) 進行更新操作 

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;       
        
Query query =  new Query();
        query.addCriteria(Criteria.where("_id").is(new ObjectId("5feafa9b47801f7dfef1bf2e")));
        Update update = new Update();
        update.set("name" , "new_set_values");
        UpdateResult result = mongoTemplate.upsert(query, update, "testDocuments");
        long count = result.getModifiedCount();
        if (count > 0) {
            return ApiResult.success("win!~");
        }

 2 . 使用MongoTemplate.execute() 回撥函式進行更新操作

            // 注意這裡 使用的 不是 Update 而是 Updates
            String execute = mongoTemplate.execute("testDocuments", mongodb -> {
            UpdateResult result = mongodb.updateMany(new Document("name", "isnert3"), Updates.set("name", "upr_execute_name"));
            long count = result.getModifiedCount();
            if (count > 0) {
                return "success";
            }
            return "error";
        });

 3 . 使用MongoDb原生SQl 進行更新操作

    db.getCollection('testDocuments').updateOne({
        name: 'new_set_values'
    }, {
        $set: {
            name: 'Mongo_set_name_new'
        }
    })
  •  查詢操作

由於是測試用

1 . 使用MongoTemplate進行查詢操作

 普通查詢

// 查詢所有
List<Document> testDocuments = mongoTemplate.find(new Query(), Document.class, "testDocuments");

// 條件查詢 , 根據_id查詢指定值
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("5feafa9b47801f7dfef1bf2e")));
mongoTemplate.find(query, Document.class, "testDocuments");
// 也可以直接使用MongoTemplate提供的 findById()
mongoTemplate.findById("5feafa9b47801f7dfef1bf2e",Document.class , "testDocuments");

// 條件查詢,查詢特定name值
Query query = new Query();
query.addCriteria(Criteria.where("name").is("huang"));
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");

// 條件查詢,查詢特定name值 ,或者age年齡大於30的
Query query = new Query();
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("name").is("huang") , Criteria.where("age").gte(30));
query.addCriteria(criteria);
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");

// 條件查詢,查詢特定name值,並且年齡大於20的
Query query = new Query();
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("name").is("huang") , Criteria.where("age").gte(20));
query.addCriteria(criteria);
List<Document> testDocuments = mongoTemplate.find(query, Document.class, "testDocuments");

//條件查詢 , 分頁查詢 skip(0)  從第0條開始 , limit(2) 查詢兩條
Query query = new Query();
query.skip(0);
query.limit(2);
mongoTemplate.find(query, Document.class, "testDocuments");

//條件查詢 , 排序 sort 可同時針對多個欄位進行排序, 不過當資料量過大時可能會出現記憶體不足
// 具體解決辦法可參照  https://blog.csdn.net/qq_42543063/article/details/111380373
Query query = new Query();
// query.with(Sort.by("age").descending()); // 倒序
query.with(Sort.by("age").ascending()); // 正序
mongoTemplate.find(query, Document.class, "testDocuments");

2 . MongoTemplate提供的回撥與正常方法別無二致, 可按照增刪改的樣例自行探索..........

二 : 聚合操作

MongoDB 中聚合(aggregate)主要用於處理資料(諸如統計平均值,求和等),並返回計算後的資料結果。

有點類似 SQL 語句中的 count(*)。


aggregate() 方法

MongoDB中聚合的方法使用aggregate()。

語法

aggregate() 方法的基本語法格式如下所示:

>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

 聚合基礎查詢

一下是本次測是使用的資料

 

  • 聚合查詢、排序、分組、分頁、Concat拼接

Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.group("name")
                        .max("age").as("maxAge")
        );
AggregationResults<Document> testDocuments = 
                mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);

等同於Mongo原生SQL如下:

查詢結果 , 可以發現 , name被當做了_id , 且只查詢出來了兩個屬性

{"_id":"upr_execute_name","maxAge":33},{"_id":"huang","maxAge":21},{"_id":"lu","maxAge":26}

 

可以將上面的聚合操作修改為如下

// 除卻max 函式外 聚合操作還提供了  avg  min  sum 等常用計算函式
Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("gender").is("男")), // 查詢條件
                Aggregation.project("name", "age", "gender")
                        .andExpression("concat('$gender', '人')").as("genderNew")
                ,// 可利用 andExpression() 繼續操作某些特定值  加減乘如 或者拼接字串
                Aggregation.group("name")
                        .max("age").as("maxAge") // 取最大年齡 , 別名為 maxAge
                .first("name").as("name") // 分組後取該組內第一條name
                .first("age").as("age")   
                .first("gender").as("gender"),
                Aggregation.skip(0L), // 始於第幾條 mongo建議使用long型別
                Aggregation.limit(2L), // 查詢多少條 
                Aggregation.sort(Sort.Direction.DESC,
                "age" , "name") // 可同時使用多欄位排序 , 需注意當資料量過大時容易造成記憶體不足 具體解決辦法 請參照 https://blog.csdn.net/qq_42543063/article/details/111380373
        );
AggregationResults<Document> testDocuments =
                mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);

查詢結果樣例為:

{"_id":"huang","maxAge":21,"name":"huang","age":21,"gender":"男"},{"_id":"lu","maxAge":26,"name":"lu","age":26,"gender":"男"}
  • 聚合查詢連結串列關聯查詢

為了驗證關聯查詢操作 , 此處需新建一個mongo的集合 , 旨在測試用 , 具體業務不嚴謹!!!



主表為  testDocuments  關聯表為  testRel 

        // 建立條件集合
        List<AggregationOperation> aggregationOptions = new ArrayList<>();
        LookupOperation lookupOperation = LookupOperation.newLookup()
                .from("testRel") // 指定關聯表
                .localField("name") // 關聯表字段
                .foreignField("name") // 關聯表字段
                .as("rel"); // 關聯表別名
        aggregationOptions.add(lookupOperation); // 作為條件新增至條件集合
        // 為關聯表建立條件
        aggregationOptions.add(Aggregation.match(Criteria.where("rel").elemMatch(Criteria.where("name").ne("").ne(null))));
        aggregationOptions.add(Aggregation.group("name")
                .max("age").as("maxAge")
                .first("name").as("name")
                .first("age").as("age")
                .first("gender").as("gender")
                .first("rel.address").as("assress"));
        // 將條件集合建立成聚合操作Aggregation
        Aggregation aggregation = Aggregation.newAggregation(aggregationOptions);
        AggregationResults<Document> testDocuments =
                mongoTemplate.aggregate(aggregation, "testDocuments", Document.class);