1.問(wèn)題
最近在做項(xiàng)目的時(shí)候碰到一個(gè)對(duì)mongoDB的數(shù)據(jù)處理,從MongoDB中拿到內(nèi)嵌文檔的時(shí)間排序的list。
一開(kāi)始考慮到直接對(duì)mongoDB中的屬性排序,后面發(fā)現(xiàn)屬性存在內(nèi)嵌文檔中,所以處理中需要用到聚合函數(shù)。
思考
(key)解決這個(gè)問(wèn)題的過(guò)程讓我學(xué)到很多,發(fā)現(xiàn)自己在解決一個(gè)問(wèn)題不僅查找問(wèn)題的姿勢(shì)不對(duì),浪費(fèi)太多時(shí)間。而且在碰到問(wèn)題之后,應(yīng)該多看看解決辦法,甚至解決了之后要去思考問(wèn)題,回顧問(wèn)題。而不是像以前一樣,解決問(wèn)題了就萬(wàn)事大吉,拋之腦后。
2.解決
需要對(duì)document中的一個(gè)tweet_list 集合中的一個(gè)屬性 timestamp_ms進(jìn)行排序。 組內(nèi)排序
使用聚合框架,通過(guò)match,unwind,sort等不同的組件創(chuàng)建一個(gè)管道。
類(lèi)似mysql中的多層嵌套子查詢(xún)。
mongoDB中js代碼
db.text.aggregate(
// Initial document match (uses index, if a suitable one is available)
[
{ $match: {
_id : ObjectId("5ca95b4bfb60ec43b5dd0db5")
}},
// Expand the scores array into a stream of documents
{ $unwind: '$tweet_list' },
{ $match: {
'tweet_list.timestamp_ms': '1451841845660'
}},
// Sort in descending order
{ $sort: {
'tweet_list.timestamp_ms': 1
}}
]
)
java實(shí)現(xiàn)此聚合函數(shù)
java中的Aggregation類(lèi),查詢(xún)條件的順序決定結(jié)果。
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(Criteria.where("_id").is(id)),
Aggregation.unwind("tweet_list"),
Aggregation.sort(Sort.Direction.ASC,"tweet_list.timestamp_ms"),
Aggregation.project("tweet_list.timestamp_ms","tweet_list.text","tweet_list.created_at")
);
AggregationResultsJSONObject> results = mongoTemplate.aggregate(agg, "text", JSONObject.class);
//System.out.println("results"+results.getRawResults()); //獲取到的結(jié)果是document
//String res = results.getRawResults();
String json = com.mongodb.util.JSON.serialize(results.getRawResults());
System.out.println("JSON serialized Document: " + json);
JSONObject jso= JSON.parseObject(json);
JSONArray resultss=jso.getJSONArray("results");
System.out.println(resultss);
3.擴(kuò)展
管道pipeline
以下的管道操作符可以按照任意順序組合在一起使用。每個(gè)操作符都會(huì)接受一連串文檔,對(duì)這些文檔做了類(lèi)型轉(zhuǎn)換后,將轉(zhuǎn)換后的文檔作為結(jié)果傳遞給下一個(gè)操作符。直到最后一個(gè)管道操作符,將結(jié)果返回給客戶(hù)端。
篩選match
盡可能將帥選放在管道的前部。兩個(gè)原因:
1.先過(guò)濾掉不需要的文檔,減少管道的工作量。
2.如果在project和group之前執(zhí)行match,查詢(xún)可以用索引。
3.不能在match中使用地理空間操作符
投射project
類(lèi)似select操作。可以用管道表達(dá)式,數(shù)學(xué)表達(dá)式,日期表達(dá)式,字符表達(dá)式,邏輯表達(dá)式等。
分組group
跟mysql中的分組比較像
排序sort
1 升序 -1 降序
限制limit
限制結(jié)果條數(shù)
跳過(guò)skip
丟棄結(jié)果中的前n個(gè)文檔
拆分unwind
把數(shù)組中的每個(gè)值拆分為單獨(dú)的文檔,例如此問(wèn)題中需要對(duì)一個(gè)document中的tweetlist進(jìn)行排序,可以使用unwind把tweetlist中的不同map拆分成不同的文檔。
結(jié)果返回
文檔
MapReduce
如果聚合框架中查詢(xún)語(yǔ)言不能不表達(dá),需要用到MapReduce。
使用:把問(wèn)題拆分為多個(gè)小問(wèn)題,把各個(gè)小問(wèn)題發(fā)送到不同的機(jī)器上,每臺(tái)機(jī)器只負(fù)責(zé)完成一部分的工作,完成之后,再把零碎的解決方案合并。
步驟:
1.映射map:把操作映射到集合中每個(gè)文檔
2.洗牌shuffle:按照鍵值分組,并將產(chǎn)生的鍵值組成列表放到對(duì)應(yīng)的鍵中。
3.化簡(jiǎn)reduce:把列表中的值化簡(jiǎn)成一個(gè)單值,值被返回,繼續(xù)shuffle,然后最終每個(gè)鍵的列表只有一個(gè)值,即最終結(jié)果,
應(yīng)用:
1.找到集合中所有鍵
2.網(wǎng)頁(yè)分類(lèi)
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
您可能感興趣的文章:- java操作elasticsearch的案例解析
- 利用Java多線(xiàn)程技術(shù)導(dǎo)入數(shù)據(jù)到Elasticsearch的方法步驟
- JAVA使用ElasticSearch查詢(xún)in和not in的實(shí)現(xiàn)方式
- java 使用ElasticSearch完成百萬(wàn)級(jí)數(shù)據(jù)查詢(xún)附近的人功能
- 使用java操作elasticsearch的具體方法
- 基于Lucene的Java搜索服務(wù)器Elasticsearch安裝使用教程
- JAVA mongodb 聚合幾種查詢(xún)方式詳解
- mongodb聚合_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- java使用elasticsearch分組進(jìn)行聚合查詢(xún)過(guò)程解析