MongoDB基於Morphia (二)demo 包含聚合彙總 多條件查詢
阿新 • • 發佈:2018-12-24
MongoDB基礎語句
注:新增欄位 也是用其中的set 但是確保實體類中有新增的屬性(使用morphia)
例如::
books是表名 “book_serial_num” : “B1013687616857538560” 為篩選條件
mongo中語句
新增欄位 如果原來有這個欄位就是更新
db.getCollection(‘books’).update({“book_serial_num” : “B1013687616857538560”},{"$set" : {“test2”:“33”}})
查詢
db.getCollection(‘books’).find({“book_serial_num” : “B1013687616857538560”})
刪除:刪除test2的欄位 後面必須為“”
db.getCollection(‘books’).update({“book_serial_num” : “B1013687616857538560”},{"$unset" : {“test2”:""}})
詳細方法demo
更新操作:
@Override public void updateTitle(String book_serial_num, String main_title) { FieldFilter filter = new FieldFilter(MonthlyPaymentActivityBooks.BOOK_SERIAL_NUM, FilterOp.EQ, book_serial_num); FieldFilter[] params = new FieldFilter[]{filter}; Query<MonthlyPaymentActivityBooks> query = this.getDao().createQuery(); for (FieldFilter filter1: params) { query.filter(filter1.getField()+filter1.getOperator().getOperator(),filter1.getValue()); } UpdateOperations<MonthlyPaymentActivityBooks> ops = this.getDao().getDs().createUpdateOperations(MonthlyPaymentActivityBooks.class).set(MonthlyPaymentActivityBooks.MAIN_TITLE, main_title); getDao().update(query,ops); }
聚合彙總操作
方式一
/** 其中paramMap 為 條件 codes為要彙總的欄位名 */ @Override public Map<String,LinkedHashMap<String,Double>> getTotalBy(Map<String,Object> paramMap, String... codes) { StringBuffer map = new StringBuffer(); map.append("function() {"); map.append(" var value ={"); for(int i=0;i<codes.length;i++){ if(i>0){ map.append(","); } map.append(codes[i]).append(":this.").append(codes[i]); } map.append("};"); map.append("emit(this.book_serial_num,value); "); map.append("}"); StringBuffer reduce = new StringBuffer(); reduce.append("function(key,values) {"); reduce.append(" var result ={"); for(int i=0;i<codes.length;i++){ if(i>0){ reduce.append(","); } reduce.append(codes[i]).append(":0"); } reduce.append("};"); reduce.append("for(var i=0;i<values.length;i++){"); for(int i=0;i<codes.length;i++){ reduce.append(" if(values[i].").append(codes[i]).append("!=undefined").append(") {"); reduce.append("result.").append(codes[i]).append("+=").append("values[i].").append(codes[i]).append(";"); reduce.append("};"); } reduce.append("};"); reduce.append("return result;"); reduce.append("}"); String result = "result"; BasicDBObject queryForMap = new BasicDBObject(); BasicDBObject queryObj = new BasicDBObject(); if (paramMap.get("start_time") != null && paramMap.get("end_time") != null) { queryObj.append("$gte", paramMap.get("start_time")); queryObj.append("$lte", paramMap.get("end_time")); queryForMap.put("report_time", queryObj); } if(paramMap.get("channelCode") != null){ queryForMap.put("channel_code", paramMap.get("channelCode")); } MapReduceOutput mapReduceOutput = dao.getCollection().mapReduce(map.toString(), reduce.toString(), result, MapReduceCommand.OutputType.REPLACE,queryForMap); DBCollection resultColl = mapReduceOutput.getOutputCollection(); DBCursor dbCursor = resultColl.find(); Map<String,LinkedHashMap<String,Double>> bookMap = new HashMap<>(); //遍歷獲得總值 while (dbCursor.hasNext()) { DBObject resultObj = dbCursor.next(); String bookId = (String)resultObj.get("_id"); LinkedHashMap<String,Double> param = new LinkedHashMap<>(); for(String code:codes){ DBObject data = (DBObject)resultObj.get("value"); if(null!=data.get(code) && !data.get(code).toString().contains("bson")) { if (param.get(code) != null) { param.put(code, param.get(code) + Double.valueOf(String.valueOf(data.get(code)))); } else { param.put(code, Double.valueOf(String.valueOf(data.get(code)))); } } } bookMap.put(bookId,param); } return bookMap; }
方式二::
/**
* 彙總查詢 可使用 同上個方法
* @param paramMap 查詢條件
* @param code 統計的欄位
*/
@Override
public void getTotalByGroup(Map<String, Object> paramMap, String[] code) {
Query<ClickRecentReport> query = dao.createQuery();
Long start_time = (Long) paramMap.get("start_time");
Long end_time = (Long) paramMap.get("end_time");
String channelCode = (String) paramMap.get("channelCode");
List<FieldFilter> params = new ArrayList<>();
params.add(new FieldFilter(ClickRecentReport.REPORT_TIME, FilterOp.GTE,start_time));
params.add(new FieldFilter(ClickRecentReport.REPORT_TIME,FilterOp.LTE,end_time));
params.add(new FieldFilter(ClickRecentReport.CHANNEL_CODE,FilterOp.EQ,channelCode));
for (FieldFilter filter : params) {
query.filter(filter.getField() + filter.getOperator().getOperator(), filter.getValue());
}
AggregationPipeline aggregationPipeline = dao.getDs().createAggregation(ClickRecentReport.class);
// String[] code = new String[]{"uv","click","click_total","pv"};
aggregationPipeline.
match(query).
group(
id(grouping("channel_code"), grouping("book_serial_num")),
grouping("uv", sum("uv")),
grouping("click", sum("click")),
grouping("click_total", sum("click_total")),
grouping("pv", sum("pv"))
);
//ClickRecentReportCopy和ClickRecentReport相同欄位 但必須進行此操作
Iterator<ClickRecentReportCopy> iterator = aggregationPipeline.aggregate(ClickRecentReportCopy.class);
System.out.println(iterator.hasNext());
while (iterator.hasNext()) {
ClickRecentReportCopy ug = iterator.next();
System.out.println(ug);
}
}
新增 彙總方式三: 基於mapreduce
@Override
public List<BookCollectionAnalyse> getCount(Long startTime, Long endTime, String channelCode) {
//根據CHANNEL_CODE彙總
BasicDBObject key = new BasicDBObject();
key.put(BookCollectionAnalyse.CHANNEL_CODE, 1);
//條件 加入條件
BasicDBObject cond = new BasicDBObject();
BasicDBObject queryObj = new BasicDBObject();
queryObj.append("$gte", startTime);
queryObj.append("$lte", endTime);
cond.put(BookPUVAnalyse.REPORT_TIME, queryObj);
if (StringUtils.isNotBlank(channelCode)) {
BasicDBObject queryObj2 = new BasicDBObject();
queryObj2.append("$eq", channelCode);
cond.put(BookCollectionAnalyse.CHANNEL_CODE, queryObj2);
}
BasicDBObject initial = new BasicDBObject();
initial.append("collection_count", 0);
//reduce 彙總內容
StringBuffer reduce = new StringBuffer();
reduce.append("function Reduce(doc, out) {");
reduce.append("out.collection_count+=doc.collection_count;");
reduce.append("out.channel_name=doc.channel_name;");
reduce.append("out.channel_code=doc.channel_code;");
reduce.append("}");
BasicDBList groupList = (BasicDBList) getDao().getCollection().group(key, cond, initial, reduce.toString());
List<BookCollectionAnalyse> result = new ArrayList<>();
//彙總資料 儲存到實體中
if (groupList != null && groupList.size() > 0) {
for (int i = 0; i < groupList.size(); i++) {
BasicDBObject obj = (BasicDBObject) groupList.get(i);
BookCollectionAnalyse bookCollectionAnalyse = new BookCollectionAnalyse();
bookCollectionAnalyse.setCollection_count(obj.getLong(BookCollectionAnalyse.COLLECTION_COUNT));
bookCollectionAnalyse.setChannel_code(obj.getString(BookCollectionAnalyse.CHANNEL_CODE));
bookCollectionAnalyse.setChannel_name(obj.getString(BookCollectionAnalyse.CHANNEL_NAME));
result.add(bookCollectionAnalyse);
}
}
return result;
}
多條件或 和 並 查詢
/**
vagueParams中為或的條件 params為並且的條件
*/
public PageList<ChannelBooks> findByPage(List<FieldFilter> params, PageBounds ageBounds, List<FieldFilter> vagueParams) {
Query<ChannelBooks> query = getDao().createQuery();
for (FieldFilter filter : params) {
Object value = filter.getValue();
if (null == value) {
continue;
}
if (value instanceof String && StringUtils.isEmpty(((String) value))) {
continue;
}
query.filter(filter.getField() + filter.getOperator().getOperator(), value);
}
if (vagueParams != null) {
Criteria[] arry = new Criteria[vagueParams.size()];
int index = 0;
for (FieldFilter filter : vagueParams) {
Object value = filter.getValue();
arry[index] = query.criteria(filter.getField()).contains(value.toString());
index++;
}
query.or(arry);
}
List<Order> orderBys = ageBounds.getOrders();
String orderby = StringUtils.EMPTY;
for (Order order : orderBys) {
String dir = (order.getDirection() == Order.Direction.ASC) ? StringUtils.EMPTY : SeparatorConstant.HYPHEN;
if (StringUtils.isNotBlank(orderby)) {
orderby += ",";
}
orderby += dir + order.getProperty();
}
if (StringUtils.isNotBlank(orderby)) {
query.order(orderby);
}
query.offset(ageBounds.getOffset());
query.limit(ageBounds.getLimit());
List<ChannelBooks> findList = getDao().find(query).asList();
//分頁
int totalCount = (int) query.countAll();
PageList<ChannelBooks> list = new PageList<>();
Pagination pagination = new Pagination(ageBounds.getPage(), ageBounds.getLimit(), totalCount);
list.setPagination(pagination);
list.addAll(findList);
return list;
}