2017-08-02 150 views
0

我有具有以下结构的mongocollection滤波器

{ 
     "id" : "abcdefg", 
     "sub" : {"field1" : "value1", "field3" : "value3"}, 
     "profile" : { 
      "array" : [ 
       {"score" : 1}, 
       {"score" : 2}, 
       {"score" : 3} 
      ] 
     } 
    } 

我想在profile.score.score过滤文档,我使用下面

Document idQuery = new Document("id", new Document("$in", ids)); 
       // ids is an array of id 
    Document idMatch = new Document("$match", idQuery); 
    Document projectArray = new Document("$project", new Document("id",1).append("profile.array", 1).append("sub", 1)); 
    Document unwindArray = new Document("$unwind", "$profile.array"); 
    Document filterQuery = new Document("profile.array.score", new Document("$gte", 2)); 
    Document filterMatch = new Document("$match", filterQuery); 
    Document groupResult = new Document("$group", new Document("_id", "$id").append("array", new Document("$push", "$profile.array")).append("sub", new Document("$push", "$sub"))); 
    List<Document> pipeLineList = new ArrayList<Document>(); 
    pipeLineList.add(idMatch); 
    pipeLineList.add(projectArray); 
    pipeLineList.add(unwindArray); 
    pipeLineList.add(filterMatch); 
    pipeLineList.add(groupResult); 
    AggregateIterable<Document> result = companyProfiles.aggregate(pipeLineList); 

通过以上做时,我具有

{ 
    "id" : "abcdefg", 
    "sub" : [ 
       {"field1" : "value1", "field3" : "value3"}, 
       {"field1" : "value1", "field3" : "value3"} 
      ] 
    "profile" : { 
     "array" : [ 
      {"score" : 2}, 
      {"score" : 3} 
     ] 
    } 
} 

子字段插入两次作为阵列中,这是不我想要的元件的结果。我应该怎么做才能有正确的结果

{ 
    "id" : "abcdefg", 
    "sub" : {"field1" : "value1", "field3" : "value3"}, 
    "profile" : { 
     "array" : [ 
      {"score" : 2}, 
      {"score" : 3} 
     ] 
    } 
} 

回答

1

更改$group阶段使用$first而不是$push以避免重复。

Document groupResult = new Document("$group", new Document("_id", "$id").append("array", new Document("$push", "$profile.array")).append("sub", new Document("$first", "$sub"))); 

或者您可以重构代码以使用$filter它取代$unwind + $match + $group

Document idQuery = new Document("id", new Document("$in", ids)); 
Document idMatch = new Document("$match", idQuery); 
Document filterQuery = new Document("$gte", Arrays.asList("$$profilearray.score", 2)); 
Document filterArray = new Document("$filter", new Document("input", "$profile.array").append("as", "profilearray").append("cond", filterQuery)); 
Document projectArray = new Document("$project", new Document("id",1).append("profile.array", filterArray).append("sub", 1)); 
List<Document> pipeLineList = new ArrayList<Document>(); 
pipeLineList.add(idMatch); 
pipeLineList.add(projectArray);