복붙노트

[SPRING] MongoDB $ aggregate $ Java Spring 데이터에서 여러 필드 푸시

SPRING

MongoDB $ aggregate $ Java Spring 데이터에서 여러 필드 푸시

Mongo 집계 그룹 검색어가 있습니다.

db.wizard.aggregate(
{
$group: {
    _id: "$title",
    versions: { $push: {version:"$version", author:"$author", dateAdded:"$dateAdded"}}
    }
})

Java Spring-Data-MongoDB에서이 쿼리가 필요합니다. 현재 솔루션은 다음과 같습니다.

    Aggregation agg = Aggregation.newAggregation(
            Aggregation.group("title").
                    push("version").as("versions")
    );

문제는 내가 메서드 (버전, 저자, dateAdded)를 밀어 더 많은 필드를 추가하는 방법을 모르겠다. Spring-Data-MongoDB로 가능합니까?

해결법

  1. ==============================

    1.BasicDbObject를 집계 파이프 라인 단계 중 하나에 직접 전달할 수 있습니다.

    BasicDbObject를 집계 파이프 라인 단계 중 하나에 직접 전달할 수 있습니다.

    Aggregation agg = newAggregation(
                group("title").
                push(new BasicDBObject
                       ("version", "$version").append
                       ("author", "$author").append
                       ("dateAdded", "$dateAdded")).as("versions"));
    
  2. ==============================

    2.참고 : MongoDB Versión 2.6 - 3.0 (호환 Java 드라이버)

    참고 : MongoDB Versión 2.6 - 3.0 (호환 Java 드라이버)

    사용자 정의 toDBObject 메소드를 구현하기 위해 org.springframework.data.mongodb.core.aggregation.AggregationOperation 클래스를 확장했습니다.

    public class GenericAggregationOperation implements AggregationOperation {
    
        private String operator;
        private DBObject query;
    
        /**
         * Default constructor.
         * 
         * @param operator MongoDB operator ($group, $sort, $project, etc..)
         * @param query MongoDB aggregation query step string
         */
        public GenericAggregationOperation(String operator, String query) {
            this(operator, (DBObject) JSON.parse(query));
        }
    
        /**
         * Default constructor.
         * 
         * @param operator MongoDB operator ($group, $sort, $project, etc..)
         * @param query MongoDB aggregation query step DBObject
         */
        public GenericAggregationOperation(String operator, DBObject query) {
            this.operator = operator;
            this.query    = query;
        }
    
        @Override
        public DBObject toDBObject(AggregationOperationContext context) {
    
            return new BasicDBObject(operator, query);
        }
    
    }
    

    귀하의 경우, 그것은 다음과 같습니다 :

    List<AggregationOperation> list = new ArrayList<AggregationOperation>();
    lista.add(new GenericAggregationOperation("$group", "{ \"_id\": \"$title\", \"versions\": { \"$push\": { \"version\":\"$version\", \"author\":\"$author\", \"dateAdded\":\"$dateAdded\"}} }"));
    
    TypedAggregation<EpisodeIndexDto> agg = Aggregation.newAggregation(
        YourClassTitleVersion.class, list);
    mongoOperations.aggregate(agg, YourClassTitleVersion.class,
        YourClassTitleVersion.class).getMappedResults();
    

    희망이 당신을 도와줍니다.

  3. ==============================

    3.새 버전 spring-data-mongodb : 2.x.x에서 AggregationOperation은 DBObject 대신 Document를 반환해야하므로 업데이트 된 클래스는 다음과 같습니다.

    새 버전 spring-data-mongodb : 2.x.x에서 AggregationOperation은 DBObject 대신 Document를 반환해야하므로 업데이트 된 클래스는 다음과 같습니다.

    import com.mongodb.BasicDBObject;
    import com.mongodb.DBObject;
    import org.bson.Document;
    import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
    import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
    
    public class GenericAggregationOperation implements AggregationOperation {
    
        private String operator;
        private DBObject query;
    
        public GenericAggregationOperation(String operator, DBObject query) {
            this.operator = operator;
            this.query = query;
        }
    
        public GenericAggregationOperation(String operator, String query) {
            this(operator, BasicDBObject.parse(query));
        }
    
        @Override
        public Document toDocument(AggregationOperationContext context) {
            return new Document(operator, query);
        }
    }
    

    또한 더 쉽게 사용할 수 있도록 유틸리티 인터페이스 (java 8+, java 7 이하에서는 클래스 utils로 대신 변환 할 수 있음)를 추가합니다.

    import com.mongodb.DBObject;
    import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
    
    public interface GenericAggregationUtils {
    
        static AggregationOperation aggregate(String operation, String query) {
            return new GenericAggregationOperation(operation, query);
        }
    
        static AggregationOperation aggregate(String operation, DBObject query) {
            return new GenericAggregationOperation(operation, query);
        }
    
    }
    

    그리고 인터페이스를 클래스에 정적으로 임포트 할 수 있습니다 :

    import static com.example.mongodb.aggregation.GenericAggregationUtils.*;
    

    그리고 다른 스프링 데이터 AggregationOperation과 함께 집계 파이프 라인에서 다음과 같이 사용하십시오.

    Aggregation aggregation = newAggregation(YourDocCollection.class,
        aggregate("$group", "{ \"_id\": \"$title\", \"versions\": { \"$push\": { \"version\":\"$version\", \"author\":\"$author\", \"dateAdded\":\"$dateAdded\"}} }"),
        sort(Sort.Direction.ASC, "title"),
        ...
    );
    
  4. from https://stackoverflow.com/questions/39393672/mongodb-aggregate-push-multiple-fields-in-java-spring-data by cc-by-sa and MIT license