mongoTemplate學習筆記


mongoTemplate的andExpression表達式

Aggregation<Post> agg = Aggregation.newAggregation(
            Record.class,
            match(Criteria.where("createAt").gte(startAt).lte(endAt)),
            project().andExpression("{$dateToString:{format:'%Y-%m-%d',date: {$add:{'$createAt',8*60*60000}}}}").as("createAt")
            ,group( "createAt").count().as("totalNum")
            ,sort(Sort.Direction.DESC, "createAt")
        );
 AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(agg, BasicDBObject.class);
 List<BasicDBObject> results = result.getMappedResults();

mongoTemplate中的project()的用法,和previousOperation()的用法

https://blog.csdn.net/hotdust/article/details/52605990

 

最近使用Spring-Data-Mongodb的API來改寫原來的代碼,遇到了一些問題,先把自己學到的一些東西總結下來。

參考:

http://www.cnblogs.com/ontheroad_lee/p/3756247.html  (這個文章特別好,很少有中文的關於Spring-Data-Mongodb的API的例子的介紹)

http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.aggregation.examples.example6 (官方文檔)

 

1,project("name", "netPrice")

    project方法的內容是你要映射的字段,相當於{$project: {sumfavour: 1, userid: 1}}。“映射”的意思,就是要顯示哪個字段,或者把某個字段內容進行處理后顯示。

2,project().and("foo").as("bar")

    如果你想要把一個字段映射成別一個名字的話,就可以用上面的方法,相當於{$project: {bar: $foo}}

3,project("a","b").and("foo").as("bar") 

    這個方法相當於上面兩個方法的結合{$project: {a: 1, b: 1, bar: $foo}}。如果單獨使用and(),后面不使用as()的話,沒有任何效果,也不會出錯。

4,project().and("_id").plus(100000000).as("statusid")

    這個語句的意思是,把_id字段加上100000000,再重新命名為"statusid"然后輸出。

5,關於previousOperation()方法

Aggregation agg = newAggregation(
    project("tags"),
    unwind("tags"),
    group("tags").count().as("n"),
    project("n").and("tag").previousOperation(),
    sort(DESC, "n")

);

    這段代碼中主要講的是previousOperation()方法的使用,想知道其它語句的含義,請參考官網文章介紹。說previousOperation之前要先說說Group語句,這里的Group語句的作用是,按“tags”字段進行分組,然后統計每個分組中的數據個數,統計的個數字段命名為“n”。輸出的結果為(這里只為粘貼了所有數據中的一條):

    "_id" : "627",

   "n" : NumberInt(16)
}

project語句的作用是,把新生成的字段”n“做為結果輸出,並且”_id“列重新命名為”tag“,然后也做為結果輸出,最后結果為:

 

    "tag" : "627",

   "n" : NumberInt(16)
}

看完結果后,我們來說一下previousOperation()的作用。previousOperation()就是把“上一次操作的結果中”的_id字段,命名為它前面and()中的名稱。所以它一般都是和and()結合使用。關於Group操作后,_id的內容的介紹,請看最下面的“關於_id字段”說明。

6,

 

  1.  
    TypedAggregation < ZipInfo > aggregation = newAggregation ( ZipInfo . class ,
  2.  
    group ( "state" , "city" )
  3.  
    . sum ( "population" ). as ( "pop" ),
  4.  
    sort ( ASC , "pop" , "state" , "city" ),
  5.  
    group ( "state" )
  6.  
    . last ( "city" ). as ( "biggestCity" )
  7.  
    . last ( "pop" ). as ( "biggestPop" )
  8.  
    . first ( "city" ). as ( "smallestCity" )
  9.  
    . first ( "pop" ). as ( "smallestPop" ),
  10.  
    project ()
  11.  
    . and ( "state" ). previousOperation ()
  12.  
    . and ( "biggestCity" )
  13.  
    . nested ( bind ( "name" , "biggestCity" ). and ( "population" , "biggestPop" ))
  14.  
    . and ( "smallestCity" )
  15.  
    . nested ( bind ( "name" , "smallestCity" ). and ( "population" , "smallestPop" )),
  16.  
    sort ( ASC , "state" )
  17.  
    );

通過nested()方法,可以把輸出的結果變成嵌套格式,例如:

 

    "object":{ "fieldA":"valueA","fieldB":"valueB"}

bind()方法是用通過已經存在的字段,來生成新的字段。例如

    and("biggestCity").nested(bind("newField", "existField"))

7,

 

  1.  
    TypedAggregation < Product > agg = newAggregation ( Product . class ,
  2.  
    project ( "name" , "netPrice" )
  3.  
    . and ( "netPrice" ). plus ( 1 ). as ( "netPricePlus1" )
  4.  
    . and ( "netPrice" ). minus ( 1 ). as ( "netPriceMinus1" )
  5.  
    . and ( "netPrice" ). multiply ( 1.19 ). as ( "grossPrice" )
  6.  
    . and ( "netPrice" ). divide ( 2 ). as ( "netPriceDiv2" )
  7.  
    . and ( "spaceUnits" ). mod ( 2 ). as ( "spaceUnitsMod2" )
  8.  
    );

可以在映射完某個字段后,還可以對字段進行加減乘除。

 

8,

 

  1.  
    TypedAggregation < Product > agg = newAggregation ( Product . class ,
  2.  
    project ( "name" , "netPrice" )
  3.  
    . andExpression ( "netPrice + 1" ). as ( "netPricePlus1" )
  4.  
    . andExpression ( "netPrice - 1" ). as ( "netPriceMinus1" )
  5.  
    . andExpression ( "netPrice / 2" ). as ( "netPriceDiv2" )
  6.  
    . andExpression ( "netPrice * 1.19" ). as ( "grossPrice" )
  7.  
    . andExpression ( "spaceUnits % 2" ). as ( "spaceUnitsMod2" )
  8.  
    . andExpression ( "(netPrice * 0.8 + 1.2) * 1.19" ). as ( "grossPriceIncludingDiscountAndCharge" )
  9.  
     
  10.  
    );

還可以用andExpression()方法,使用一些mongo中的函數,例如:substr等。更重要的一點,還可以使用SpringSpEL表達式。上面的例子就是使用了表達式。下面是使用和不使用表達式的例子:

 

使用表達式:

 

 1+(q +1)/(q -1)

不使用表達式:

 

 

  1.  
    { "$add" : [ 1 , {
  2.  
    "$divide" : [ {
  3.  
    "$add" :[ "$q" , 1 ]}, {
  4.  
    "$subtract" :[ "$q" , 1 ]}
  5.  
    ]
  6.  
    }]}

 

而且,而且,在表達式內部還可以設置用外部變量進行替換。

 

  1.  
    TypedAggregation < Product > agg = newAggregation ( Product . class ,
  2.  
    project ( "name" , "netPrice" )
  3.  
    . andExpression ( "(netPrice * (1-discountRate) + [0]) * (1+taxRate)" , shippingCosts ). as ( "salesPrice" )
  4.  
    );

[0]的位置,就會被后面的shippingCosts參數的內容給替換。

 

 

 

 

關於_id字段

    _id字段是插入到數據庫時自動生成的。在使用Group等聚合操作后,_id的內容會隨着變化。例如:

1,{$group:{_id:'$statusid', sumfavour:{$sum:1}}}

這個語句的意思是,按照statusid字段進行分組,並統計每個分組的數據個數,被統計的個數字段命名為“sumfavour”。

從下面的輸出的內容可以看到,_id內容就是statusid字段的內容。


    "sumfavour" : NumberInt(16), 
    "statusid" : "627"
}

 

2,{$group:{_id:{'statusid':'$statusid','userid':'$userid'}, sumfavour:{$sum:1}}}

這個語句的意思是按兩個字段的內容進行排序。當以兩個或以上的字段進行分組時,必須這么寫,下面的例子都是錯誤的:

X:$group:{_id:{'$statusid','$userid'}}

X:$group:{_id:{'statusid','userid'}}

從這次分組完后的內容可以看到,_id的內容是statusid和userid兩個字段的內容的組合。


    "_id" : {
        "statusid" : NumberInt(538), 
        "userid" : NumberInt(416347)
    }, 
    "sumfavour" : NumberInt(1)
}

可以看出_id字段


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM