1. 程式人生 > >MongoDB基於Morphia (二)demo 包含聚合彙總 多條件查詢

MongoDB基於Morphia (二)demo 包含聚合彙總 多條件查詢

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;
    }