Spring Data api常用mongoDB操作(不定期更新)

查詢collection中指定屬性

1.直接通過Query查詢

 Query query=new Query();
        Criteria criteria=new Criteria();
        criteria.and("accountId").is(accountId);
        query.addCriteria(criteria);
        query.fields().include("templateId").include("templateName").include("templateDesc");//查詢指定屬性
        List<FormTemplate> formTemplates = mongoTemplate.find(query, FormTemplate.class);

轉義成查詢json

{ "accountId" : { "$numberLong" : "2" } } fields: Document{{templateName=1, templateDesc=1, _id=1}}

2.使用aggregate(集合)算子進行兩階段管道操作

TypedAggregation<Dog> countAggr = Aggregation.newAggregation(Dog.class,
                Aggregation.match(criteria), Aggregation.project("filed1","filed2"));//選擇指定屬性
        AggregationResults<Dog> aggregate = mongoTemplate.aggregate(countAggr, Dog.class);
        List<Dog> mappedResults = aggregate.getMappedResults();

對document進行"存在則更新不存在則新增"操作

mongoDB在進行數據持久化時,採用離散存儲方式。即刪除的document佔用的存儲空間並不會被回收。所以儘量不要對mongoDB進行頻繁刪除新增操作。對於數據庫操作中“存在則更新不存在則新增”的業務場景。可採用upsert方式執行。

        Query query=new Query(where("_id").is(formTemplate.getTemplateId()));
        Update update=new Update();
        update.set("controlList",formTemplate.getControlList());
        update.set("createId",formTemplate.getCreateId());
        update.set("createTime",formTemplate.getCreateTime());
        update.set("updateId",formTemplate.getUpdateId());
        update.set("updateTime",formTemplate.getUpdateTime());
        update.set("accountId",formTemplate.getAccountId());
        UpdateResult upsertResult = mongoTemplate.upsert(query, update);
        boolean res = upsertResult.wasAcknowledged();

MongoCursor使用

mongoDB每次從數據庫加載數據時默認僅使用16MB的緩存空間,如果需要讀取大量的數據,例如讀取上百萬的document到內存中,超過16MB的緩存大小會報錯。爲了解決如上問題,mongo提供了遊標的方式分段的去加載。參見mongo官方文檔關於Cursor的介紹。
對常見的 db.collection.find()操作,返回的就是一個cursor,一個cursor返回的記錄條數可以通過DBQuery.shellBatchSize=50命令進行設置,也可以通過DBQuery.shellBatchSize命令進行查看。mongodb-driver提供了對Cursor的封裝——MongoCursor。而Spring data mongoDB本質是基於mongodb-driver的,所以可以採用MongoCursor分階段的將大容量數據加載到內存中。
示例代碼:

Query query=new Query();
        query.addCriteria(criteria);
        //batchSize設置一次性加載的記錄條數,noCursorTimeout設置遊標的過期時間爲永遠不過期,直到加載完所有記錄爲止,對於大數據量的加載需要設置此屬性,如果不設置,mongoDB會默認在10分鐘後關閉此cursor
        MongoCursor<Document> iterator = mongoTemplate.getCollection("osgidevices").find().batchSize(100)
                .noCursorTimeout(true).iterator();
        List<OsigiDevices> all = new ArrayList<OsigiDevices>();
        int i=0;
        while (iterator.hasNext()){
            Document document = iterator.next();
            //使用mongoConverter將Document轉換成對應java實體類
            all.add(mongoConverter.read(OsigiDevices.class,document));
            i++;
            if(i%10000==0){
                System.out.println("已導入"+i+"條數據");
            }
        }

注意MongoCursor如果遍歷完所有記錄會自動關閉,如果僅僅是遍歷了一條記錄需要顯式關閉MongoCursor。例如:

...
Document doc1 = mongoCursor.next();//只從iterator中取一條記錄
mongoCursor.close();

如果不關閉,相當於一直打開的一個數據庫連接,佔用內存,雖然會在一定時間後被mongoDB關閉,但是併發量大時仍然會有內存泄漏的風險。

可參考如下文章
https://stackoverflow.com/questions/24260677/mongodb-why-should-we-close-the-cursor-after-it-is-used

基於Document對mongoDB原生js操作命令轉義

js是直接與mongoDB交互的官方方式,具體的交互指令是封裝了一些函數操作符的json。spring data mongoDB本質是對mongoClient進行封裝,使用Document對象描述json。對於spring data mongoDB api不熟悉的同學可以使用mongoClient進行操作。
例如如下原生js集合操作,對osgidevices表中數據匹配lastday等於20190719,countycode存在的字段進行提取,然後按照areacode和countycode兩個字段進行分組,並將activecount字段求和。
在這裏插入圖片描述使用mongoClient+document的方式則是:

Document matchdoc = new Document("$match",
                new Document("lastday", date).append("countycode", new Document("$exists", true)));

Document groupdoc = new Document("$group",
                new Document("_id",
                        new Document("areacode", "$areacode").append("countycode", "$countycode")
                                .append("countyname", "$countyname").append("manufacturer",
                                        "$manufacturer")).append("activecount",
                                                new Document("$sum", 1)));
MongoClient mongoClient=new MongoClient("url information");
MongoCursor<Document> iterator = mongoClient.getDatabase("").getCollection("")
                .aggregate(aggregatelist).iterator();

獲得一個MongoCursor對象,進行迭代得到結果。

mongoDB根據多屬性是否存在查詢相關記錄

db.getCollection('osgiSpeedResult').find(
{'webTestInfo':{ $exists: true }},
{'osgiDownloadTestInfo':{ $exists: false }},
{'osgiUploadTestInfo':{ $exists: false }});

mongoDB刪除根據查詢條件篩選的記錄

db.getCollection('osgiSpeedResult').deleteMany(
{'webTestInfo':{ $exists: true }},
{'osgiDownloadTestInfo':{ $exists: false }},
{'osgiUploadTestInfo':{ $exists: false }});

mongoDB對查詢出的記錄根據時間倒敘排序並取前n條記錄

db.getCollection('osgiSpeedResult').find(
{'webTestInfo':{ $exists: true }},
{'osgiDownloadTestInfo':null},
{'osgiUploadTestInfo':null}).sort({ time : -1 }).limit(10);

mongoDB根據屬性數據類型進行查詢

$type操作符
檢測類型
種類 代號 別名
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”
JavaScript 13 “javascript”
Symbol 14 “symbol”
JavaScript (with scope) 15 “javascriptWithScope”
32-bit integer 16 “int”
Timestamp 17 “timestamp”
64-bit integer 18 “long”
Min key -1 “minKey”

原文鏈接:https://blog.csdn.net/demon_LL/article/details/60870824

查詢指定屬性是字符串的類型

db.getCollection('osgiSpeedResult').find(
{'osgiDownloadTestInfo':{ $type : 2 }});

mongoClient連接mongoDB

maven引入mongo driver包

		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongodb-driver</artifactId>
		</dependency>

連接mongoDB,構建MonogoClient對象,建議可以使用單例模式創建

public static void init(String mongolist, String username, String password) {
        MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
        builder.readPreference(ReadPreference.secondaryPreferred());
        MongoClientURI clientURI = null;
        if (StringUtils.isNotBlank(username) || StringUtils.isNotBlank(password)) {
            clientURI = new MongoClientURI(
                    "mongodb://" + username + ":" + password + "@" + mongolist, builder);
        } else {
            clientURI = new MongoClientURI("mongodb://" + mongolist, builder);
        }
        client = new MongoClient(clientURI);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章