1

、私のアグリゲーションパイプラインの$projectステップがどのように見えるにはどうすればよい:手で書かれたとき、私は春データモンゴで集約投影視野内の巣フィールドを

{ 
    "$project":{ 
     "DRIVE":{ 
      "componentSummary":{"manufacturer" : "$_id.DRIVE_manufacturer"}, 
      "componentCount":"$_id.DRIVE_componentCount" 
     }, 
     "hostnames":1, 
     "_id":0 
    } 
    } 

私は私が作成しProjectionOperationBulderを使用できることを理解します何かなどを作るために、(builder.nestedを使用して)ネストの単一レベル、言う:

{ 
    "$project":{ 
     "DRIVE":{ 
      "manufacturer":"$_id.DRIVE_manufacturer" 
     }, 
     "hostnames":1, 
     "_id":0 
    } 
    } 

しかしFieldインタフェースは専用文字列名が可能になりますように私は、どのように巣別のレベルを深くに把握することができないようとString ta rgetを定義することはできません。Fieldをターゲットとして定義します。

ありがとうございます!

答えて

0

これに苦しんでいる他の人のために - Spring Data Mongoは本書(安定版1.9.5)の時点でマルチレベルネストをネイティブにサポートしていません。しかし、1.9.3では、あなた自身で動作を定義できるようにするcustom AggregationExpressionsをサポートしています。このルートを下っていくと、ほとんどの場合手作業でクエリ用のJSONを構築する必要があることに注意してください。私の実装はかなり素早く汚れていますが、参考のためです。

 protected class NestedField implements Field { 

private String name; 
private List<Field> fields; 

public NestedField(String name, List<Field> fields) { 
    this.name = name; 
    this.fields = fields; 
} 

public List<Field> getFields() { 
    return fields; 
} 

@Override 
public String getName() { 
    return name; 
} 

private String escapeSystemVariables(String fieldTarget) { 
    if (fieldTarget.startsWith("_id")) { 
    return StringUtils.prependIfMissing(fieldTarget, "$"); 
    } else { 
    return fieldTarget; 
    } 
} 

private String encloseStringInQuotations(String quotable) { 
    return JSON.serialize(quotable); 
} 

private String buildSingleFieldTarget(Field field) { 
    if (field instanceof NestedField) { 
    return String.join(":", encloseStringInQuotations(field.getName()), field.getTarget()); 
    } 
    return String.join(":", encloseStringInQuotations(field.getName()), encloseStringInQuotations(escapeSystemVariables(
    field.getTarget()))); 
} 

private String buildFieldTargetList(List<Field> fields) { 
    List<String> fieldStrings = new ArrayList<>(); 
    fields.forEach(field -> { 
    fieldStrings.add(buildSingleFieldTarget(field)); 
    }); 
    return Joiner.on(",").skipNulls().join(fieldStrings); 
} 

@Override 
public String getTarget() { 
    // TODO Auto-generated method stub 
    return String.format("{%s}", buildFieldTargetList(fields)); 
} 


@Override 
public boolean isAliased() { 
    return true; 
} 

}

protected class NestedProjection implements AggregationExpression { 

private List<Field> projectedFields; 

public NestedProjection(List<Field> projectedFields) { 
    this.projectedFields = projectedFields; 

}@Override 
public DBObject toDbObject(AggregationOperationContext context) { 
    DBObject projectionExpression = new BasicDBObject(); 
    for(Field f : projectedFields) { 
    //this is necessary because if we just put f.getTarget(), spring-mongo will attempt to JSON-escape the string 
    DBObject target = (DBObject) com.mongodb.util.JSON.parse(f.getTarget()); 
     projectionExpression.put(f.getName(), target); 


    } 
    return projectionExpression; 
} 

}

関連する問題