2016-11-18 38 views
0

我面臨的情況是,我需要從MongoDB中的集合中查詢結果。我想使用$ group將我的集合基於一個字段進行聚合。但我希望我的結果中有剩餘的字段,但沒有在這些字段上應用任何聚合函數,如($ first,$ sum等)。這些剩餘的字段應該在數組中。如何使用聚合對Mongo集合進行分組,同時我還需要其他文件

Example: My collection: 

------------------------------------------------------------------------- 
| name | age | sex | province | city| area | address | 
------------------------------------------------------------------------- 
| A | 22 | m | Manglr | p1 | c1 | a1 | 
| A | 22 | m | Kolkt | p2 | c2 | a2 | 
| B | 24 | m | Mumb | p3 | c3 | a3 | 
| B | 24 | m | Koch | p4 | c4 | a4 | 
| B | 24 | m | Hydrbd | p5 | c5 | a5 | 
------------------------------------------------------------------------- 

Result I want: ($group by 'name' field only) 

[ 
    { 
    "name" : 「A」, 
    "province" : [「Manglr", ‘Kolkt’] 
    "city" : [「p1」, ‘p2’], 
    "area" : [「c1」, ‘c2’], 
    "address" : [「a1」, ‘a2’], 
}, 
    { 
    "name" : 「B」, 
    "province" : [「Mumb", ‘Koch’, 'Hydrbd'] 
    "city" : [「p3」, ‘p4’,」p5」], 
    "area" : [「c3」, ‘c4’,」c5」], 
    "address" : [「a3」, ‘a4’,’a5’], 
} 
] 

Please anyone help me to create a Mongo Query or Java code 
+0

請添加你到目前爲止嘗試過的。 – Veeram

回答

1

你可以嘗試這樣的事情。根據需要分組並推送其他字段。

aggregate([{ 
    "$group": { 
     "_id": "$name", 
     "province": { 
      $push: { 
       "key": "$province" 
      } 
     }, 
     "city": { 
      $push: { 
       "key": "$city" 
      } 
     }, 
     "area": { 
      $push: { 
       "key": "$area" 
      } 
     }, 
     "address": { 
      $push: { 
       "key": "$address" 
      } 
     } 
    } 
}, { 
    "$project": { 
     "_id": 0, 
     "name": "$_id", 
     "province": "$province.key", 
     "city": "$city.key", 
     "area": "$area.key", 
     "address": "$address.key" 
    } 
}]) 

樣本輸出:

{ "province" : [ "Manglr", "kokat" ], "city" : [ "p1", "p2" ], "area" : [ "c1", "c2" ], "address" : [ "a1", "a2" ], "name" : "A" } 
{ "province" : [ "Mumb", "Koch" ], "city" : [ "p3", "p4" ], "area" : [ "c3", "c4" ], "address" : [ "a3", "a4" ], "name" : "B" } 
+0

OP希望其他字段自動聚合。 – gzc

+0

你認爲這甚至有可能嗎?我會等待OP確認。 – Veeram

0

我不知道MongoDB的方式,但以下是你可以做什麼的Java。

package com.grs.stackOverFlow.pack05; 

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
import java.util.Map; 
import java.util.Map.Entry; 
import java.util.stream.Collectors; 


class UserAccumulated{ 
    private String name; 
    private List<String> city; 
    private List<Integer> age; 
    private List<Character> sex; 

    public UserAccumulated(){ 
     city=new ArrayList<>(); 
     age=new ArrayList<>(); 
     sex=new ArrayList<>(); 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public List<String> getCity() { 
     return city; 
    } 

    public void setCity(List<String> city) { 
     this.city = city; 
    } 

    public List<Integer> getAge() { 
     return age; 
    } 

    public void setAge(List<Integer> age) { 
     this.age = age; 
    } 

    public List<Character> getSex() { 
     return sex; 
    } 

    public void setSex(List<Character> sex) { 
     this.sex = sex; 
    } 

    public void addAge(Integer age2) { 
     age.add(age2); 
    } 

    public void addCity(String city2) { 
     city.add(city2); 
    } 

    public void addSex(Character sex2) { 
     sex.add(sex2); 
    } 


    public String toString(){ 
     return String.format("{name:%s,cities : %s, sex: %s, age: %s}", name,city,sex,age); 
    } 

} 

public class User { 
    private String name,city; 
    private Integer age; 
    private Character sex; 


    public User(String name, String city, Integer age, Character sex) { 
     super(); 
     this.name = name; 
     this.city = city; 
     this.age = age; 
     this.sex = sex; 
    } 

    public static void main(String...args){ 
     //create a sample list ..you have to replace with code to retrieve data from mongo db 
     List<User> rows = Arrays.asList(new User("A", "Manglr", 22, 'm'), 
         new User("A", "Manglr", 22, 'm'), 
         new User("B", "addad", 22, 'm'), 
         new User("C", "addsadad", 22, 'm'), 
         new User("C", "sadd", 21, 'm')); 


     //aggregating 
     List<UserAccumulated> result=new ArrayList<>(); 
     //parallestream if many records else use stream 
     Map<String, List<User>> map = rows.parallelStream().collect(Collectors.groupingBy(User::getName)); 

     for(Entry<String, List<User>> entry: map.entrySet()){ 
      UserAccumulated userA=new UserAccumulated(); 
      userA.setName(entry.getKey()); 
      for(User user : entry.getValue()){ 
       userA.addAge(user.getAge()); 
       userA.addCity(user.getCity()); 
       userA.addSex(user.getSex()); 
      } 
      result.add(userA); 
     } 


     for(UserAccumulated a: result) 
      System.out.println(a); 

    } 

    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getCity() { 
     return city; 
    } 
    public void setCity(String city) { 
     this.city = city; 
    } 
    public Integer getAge() { 
     return age; 
    } 
    public void setAge(Integer age) { 
     this.age = age; 
    } 
    public Character getSex() { 
     return sex; 
    } 
    public void setSex(Character sex) { 
     this.sex = sex; 
    } 

} 

輸出看起來是這樣的:

{ name: A,cities : [Manglr, Manglr], sex: [m, m], age: [22, 22]} {name:B,cities : [addad], sex: [m], age: [22]} {name:C,cities : [addsadad, sadd], sex: [m, m], age: [22, 21]} 

我沒拿你的所有列,以保持它的簡單。我不確定它與您的實際數據量有多快。但如果性能問題讓我知道。

相關問題