mongodb語法與spring實現

mongodb語法

參考文檔:https://docs.mongodb.com/manual/reference/

 

BSON Types

BSON Type有2種標識符,整形和字符串

類型 數值 字符串 說明  
Double 1 “double”    
String 2 “string”    
Object 3 “object”    
Array 4 “array”    
Binary data 5 “binData”    
Undefined 6 “undefined” Deprecated.  
ObjectId 7 “objectId”    
Boolean 8 “bool”    
Date 9 “date”    
Null 10 “null”    
Regular Expression 11 “regex”    
DBPointer 12 “dbPointer” Deprecated.  
JavaScript 13 “javascript”    
Symbol 14 “symbol” Deprecated.  
JavaScript (with scope) 15 “javascriptWithScope”    
32-bit integer 16 “int”    
Timestamp 17 “timestamp”    
64-bit integer 18 “long”    
Decimal128 19 “decimal” New in version 3.4.  
Min key -1 “minKey”    
Max key 127 “maxKey”    

可以使用$type操作符使用這些類型。

BSON特定類型

ObjectId

近似唯一,快速生成,已排序的類型,12byte

String

UTF-8格式,

Timestamps

Date

64位整形,從1970.01.01開始的毫秒數。

 

查詢和投影操作符

Query Selectors
Name 意義
比較操作符
$eq 相等
$gt 大於
$gte 大於等於
$in 包含在集合中
$lt 小於
$lte 小於等於
$ne 不等於
$nin 不在集合中
邏輯操作符
$and AND
$not NOT
$nor 同時滿足2個條件的,則爲false
$or OR
元素操作符
$exists 字段存在
$type 字段類型爲指定類型
表達式計算  
$expr  
$jsonSchema  
$mod  
$regex 正則表達式
$text  
$where  
地理空間  
$geoIntersects  
$geoWithin  
$near  
$nearSphere  
數組操作符  
$all 包含所有指定的元素
$elemMatch 存在元素匹配所有指定條件
$size 指定數組大小
二進制操作  
$bitsAllClear  
$bitsAllSet  
$bitsAnyClear  
$bitsAnySet  
註釋  
$comment  
投影  
$ 投影第一個數組元素
$elemMatch 投影第一個匹配條件的元素
$meta  
$slice  

Update操作

操作符 說明 語法
字段操作
$currentDate 設置字段值爲當前日期  
$inc 字段值加上指定值  
$min 僅當指定值小於字段值時更新  
$max 僅當指定值大於字段值時更新  
$mul 字段值乘以指定值  
$rename 字段重命名  
$set 設置字段值爲指定值  
$setOnInsert 當文檔新增時設置值。  
$unset 移除字段值  
 
數組操作
$ 代指匹配查詢條件的第一個元素  
$[] 代指匹配查詢條件的所有元素  
$[<identifier>] 代指匹配arrayFilters的所有元素  
$addToSet 如果元素不存在則加入數組  
$pop 移除第一或最後的元素  
$pull 移除匹配條件的所有元素  
$push 增加一個元素到數組  
$pullAll 移除匹配一個集合的所有元素  
修飾
$each 修飾$push,$addToSet,循環數組中的每個元素當做一個對象,而不是整個數組作爲一個對象  
$position 修飾$push,指定插入位置  
$slice 修飾$push,限制修改數組的大小  
$sort 修飾$push,排序數組  
 
位運算
$bit Performs bitwise ANDOR, and XOR updates of integer values.  

聚合管道階段

MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢後將結果傳遞給下一個管道處理。管道操作是可以重複的。
表達式:處理輸入文檔並輸出。表達式是無狀態的,只能用於計算當前聚合管道的文檔,不能處理其它的文檔。

集合聚合

db.collection.aggregate()

除了$out, $merge, and $geoNear,所有階段都可以出現多次。

Stage Description 示例
$addFields 增加新字段到文檔中,類似$project$set is an alias for $addFields.  
$bucket    
$bucketAuto    
$collStats    
$count 文檔總數  
$facet    
$geoNear 輸出接近某一地理位置的有序文檔  
$graphLookup    
$group 分組 { $group: { _id: null, count: { $sum: 1 } } }
$indexStats    
$limit 取n條記錄 { $limit : 5 }
$listSessions    
$lookup 從另外一個文檔引入字段  
$match 用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操作。 { $match : { score : { $gt : 70, $lte : 90 } } }
$merge 把結果輸出到指定collection  
$out 把結果輸出到指定collection { $out: "<output-collection>" }
$planCacheStats    
$project 修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。 $project : {   title : 1,author : 1 ,}
$redact    
$replaceRoot replacementDocument代替當前文檔 { $replaceWith: <replacementDocument> }
$replaceWith 同$replaceRoot  
$sample 隨機取樣 { $sample: { size: 3 } }
$set 增加字段 { $set: { <newField>: <expression>, ... } }
$skip 跳過n條記錄 { $skip : 5 }
$sort 排序 { $sort : { age : -1, posts: 1 } }
$sortByCount 分組count,再倒序 { $sortByCount: "$tags" }
等價於:
{ $group: { _id: <expression>, count: { $sum: 1 } } },
{ $sort: { count: -1 } }
$unset 排除字段 { $unset: [ "<field1>", "<field2>", ... ] }
$unwind 把數組屬性平鋪,1條記錄會平鋪成n條記錄 {$unwind:    {
      path: <field path>,
      includeArrayIndex: <string>, //保存元素索引的新字段
      preserveNullAndEmptyArrays: <boolean> //true:path爲null, missing,empty array,輸出文檔。false:不輸出    }
}

 

數據庫聚合

db.aggregate( [ { <stage> }, ... ] )

since 3.6

 

聚合管道操作(標量函數)

Name Description 示例
數學計算
$abs 求絕對值  
$add 加法  
$ceil 大於等於指定值的最小整數  
$divide 除法  
$exp 指數  
$floor 小於等於指定值的最大整數  
$ln 自然對數  
$log 對數  
$log10 10爲底對數  
$mod 求模  
$multiply 乘法  
$pow 求冪  
$round round  
$sqrt 求二次根  
$subtract 減法  
$trunc 截斷  
數組操作
$arrayElemAt 求index  
$arrayToObject 數組轉document  
$concatArrays 連接數組  
$filter 過濾  
$in 在集合中  
$indexOfArray 第一個匹配的index  
$isArray 是否數組  
$map map  
$objectToArray 對象轉數組  
$range    
$reduce    
$reverseArray    
$size 數組大小  
$slice 數組切片  
$zip 合併2個數組  
邏輯表達式
$and and  
$not not  
$or or  
比較操作符
$cmp 比較2個操作數  
$eq 相等  
$gt 大於  
$gte 大於等於  
$lt 小於  
$lte 小於等於指定值的最大整數  
$ne 不等  
條件操作符
Name Description  
$cond    
$ifNull    
$switch    
日期操作
$dateFromParts    
$dateFromString    
$dateToParts    
$dateToString    
$dayOfMonth    
$dayOfWeek    
$dayOfYear    
$hour    
$isoDayOfWeek    
$isoWeek    
$isoWeekYear    
$millisecond    
$minute    
$month    
$second    
$toDate    
   
$week    
$year    
$add    
$subtract    
字面表達式
$literal    
對象表達式
$mergeObjects    
$objectToArray    
集合操作
$allElementsTrue    
$anyElementTrue    
$setDifference    
$setEquals    
$setIntersection    
$setIsSubset    
$setUnion    
字符串操作
$concat    
$dateFromString    
$dateToString    
$indexOfBytes    
$indexOfCP    
$ltrim    
   
$regexFind    
   
$regexFindAll    
   
$regexMatch    
   
$rtrim    
   
$split    
$strLenBytes    
$strLenCP    
$strcasecmp    
$substr    
$substrBytes    
$substrCP    
$toLower    
$toString    
   
$trim    
   
$toUpper    
文本操作
$meta    
三角 函數
$sin    
$cos    
$tan    
$asin    
$acos    
$atan    
$atan2    
$asinh    
$acosh    
$atanh    
$degreesToRadians    
$radiansToDegrees    
類型操作
$convert Converts a value to a specified type.(since4.0)  
$toBool Converts value to a boolean.since4.0  
$toDate Converts value to a Date.since4.0  
$toDecimal Converts value to a Decimal128.since4.0  
$toDouble Converts value to a double.since4.0  
$toInt Converts value to an integer.since4.0  
$toLong Converts value to a long.since4.0  
$toObjectId Converts value to an ObjectId.since4.0  
$toString Converts value to a string.since4.0  
$type Return the BSON data type of the field.  
聚合操作
$addToSet    
$avg    
$first    
$last    
$max    
$mergeObjects    
$min    
$push    
$stdDevPop    
$stdDevSamp    
$sum    
Accumulators (in Other Stages)
$avg    
$max    
$min    
$stdDevPop    
$stdDevSamp    
$sum    
變量操作
$let    

spring實現

文檔結構

{
    _id: ObjectId("5dbbe8ce79829800070b2374"),
    SMD: {
        source: {
            DSN: "XXXX",
            KEY: "5da31fa07c2a5e497e8ded8c844e38bd"
        },
        infofragment: [
            {
                storagetype: "inner",
                format: "origin",
                filestore: {
                    fsname: "爬蟲",
                    filename: "井場調查基本數據表",
                    fileid: "5dbbe8ce79829800070b2373"
                },
                adapter: { }
            }
        ],
        services: [
            {
                name: "DataImport",
                handledtime: ISODate("2019-11-01T08:11:58.369Z"),
                version: "1.0"
            },
            {
                name: "TagIdentify",
                handledtime: ISODate("2020-03-01T13:30:41.006Z")
            }
        ],
        quality: {
            status: NumberInt("1"),
            checktime: ISODate("2020-03-01T13:47:38.289Z"),
            version: "EPModel:1"
        },
        timestamp: ISODate("2020-03-01T13:30:41.007Z"),
        tenantid: "XXXX"
    },
    UMD: {
        creator: null,
        bd: "油氣資源詳探",
        ru: null,
        pt: "井場調查基本數據表",
        bw: "基礎研究",
        bot: "井",
        root: null,
        createdate: null,
        publisher: null,
        title: "井場調查基本數據表",
        bo: "",
        bp: "井場調查",
        ds: "鑽井"
    },
    version: NumberInt("42702")
}

說明:

UMD下屬性是不固定的。

查詢

1、通過json字符串構造查詢對象

Document filter = Document.parse(filter.toJSONString(0));
String collectionName = mongoTemplate.getCollectionName(AppData.class);
MongoCollection collection = mongoTemplate.getCollection(collectionName);

long count = collection.countDocuments(filter);

FindIterable<Document> found = collection.find(filter);

2、正則表達式

            Document doc = new Document();
            doc.put("$regex", request.getTitle());
            doc.put("$options", "i");

            filter.put(PATH_UMD_TITLE, doc);

或者

criteriaAll.and(AppData.PATH_UMD_PT).regex(request.getPt(), "i");

 

聚合

1、根據Services.name作爲分組條件,統計數據,services元素展開

// { "$unwind" : "$SMD.services"}
UnwindOperation unwindOperation = Aggregation.unwind("SMD.services");

Criteria criteria = Criteria.where(AppData.PATH_SMD_TENANT).is(tenantId);
MatchOperation matchOperation = Aggregation.match(criteria);

//{ "$project" : { "servicename" : "$SMD.services.name" }}
ProjectionOperation projectionOperation = Aggregation.project().and("SMD.services.name").as("servicename");
//{ "$group" : { "_id" : { "servicename" : "$servicename"} , "total" : { "$sum" : 1}}}
GroupOperation groupOperation = Aggregation.group("servicename"
).count().as("total");

//========統計所有記錄
Aggregation aggregationAll = Aggregation.newAggregation(
        matchOperation
        , unwindOperation
        , projectionOperation
        , groupOperation

        , Aggregation.project("servicename", "total")

                .and("servicename").previousOperation()
);

AggregationResults resultAll = mongoTemplate.aggregate(aggregationAll, AppData.class, ServiceCountEntity.class);

List<ServiceCountEntity> valuesAll = resultAll.getMappedResults();

return valuesAll.stream().collect(Collectors.toMap(
        ServiceCountEntity::getServiceName
        , ServiceCountEntity::getTotal

));

2、根據UMD指定的字段統計

Criteria criteria = Criteria.where(AppData.PATH_SMD_TENANT).is(tenantId);

String path = StrUtil.format("UMD.{}", tag);

GroupBy groupBy = GroupBy.key(path).initialDocument("{}").reduceFunction("function(doc, prev){}");

GroupByResults r = mongoTemplate.group(criteria, mongoTemplate.getCollectionName(AppData.class), groupBy, BasicDBObject.class);
List<Document> valuesAll = (List<Document>) r.getRawResults().get("retval");

return valuesAll.size();

 

 

修改

1、通過id查詢文檔,並修改UMD屬性

Criteria criteriaId = Criteria.where("_id").is(new ObjectId(id));
Query query = new Query(criteriaId);

Update update = new Update();

//更新UMD
for (Map.Entry<String, Object> entry : umd.entrySet()) {
    update.set(StrUtil.format("UMD.{}", entry.getKey()), entry.getValue());
}


mongoTemplate.updateFirst(query, update, AppData.class);

2、修改Services下元素,通過name匹配,如果不存在則插入元素

Criteria criteriaId = Criteria.where("_id").is(new ObjectId(id));
Query query = new Query(criteriaId);

Document service = new Document();
service.put("name", "TagIdentify");


Update update = new Update();
//刪除一個匹配的數組元素
update.pull("SMD.services",service);

//先更新一次,如果service存在(name相同),則刪除。
mongoTemplate.updateFirst(query, update, AppData.class);

service.put("handledtime", new Date());
service.put("version", "1.0");

Update updateAdd = new Update();
//新增服service
updateAdd.addToSet("SMD.services", service);

mongoTemplate.updateFirst(query, updateAdd, AppData.class);

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章