복붙노트

[SPRING] 파이프 라인 집계 봄 데이터 MongoDB를 조회

SPRING

파이프 라인 집계 봄 데이터 MongoDB를 조회

어떻게 자바 봄 응용 프로그램에서 사용하는 쿼리에 다음 MongoDB의 쿼리를 변환 할 것인가? 나는 제공된 조회 방법으로 파이프 라인을 사용하는 방법을 찾을 수 없습니다.

저는 여기에 변환을 시도하고있는 쿼리입니다. 나는 또한 반환 객체의 그룹화 된 컬렉션으로 유지하기 위해 deliveryZipCodeTimings을 원하는대로 내가 $ 사용 긴장하지 않은 점에 유의하고 싶다.

db.getCollection('fulfillmentChannel').aggregate([
    {
        $match: {
            "dayOfWeek": "SOME_VARIABLE_STRING_1"
        }
    },
    {
        $lookup: {
            from: "deliveryZipCodeTiming",
            let: { location_id: "$fulfillmentLocationId" },
            pipeline: [{
                $match: {
                    $expr: {
                        $and: [
                            {$eq: ["$fulfillmentLocationId", "$$location_id"]},
                            {$eq: ["$zipCode", "SOME_VARIABLE_STRING_2"]}
                        ]
                    }
                }
            },
            { 
                $project: { _id: 0, zipCode: 1, cutoffTime: 1 } 
            }],
            as: "deliveryZipCodeTimings"
        }
    },
    {
        $match: {
            "deliveryZipCodeTimings": {$ne: []}
        }
    }
])

해결법

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

    1.따라서 최신의 그리고 최고의 기능 중 일부 아직 단순히 API를 통해 잘 액세스 할 수 없습니다 - 드라이버는 현재 언어 MongoDB를 제공하는 기능 뒤에 조금 거의 항상. 나는이 그 사례 중 하나이며 문자열을 사용에 의존해야합니다 두렵다. 종류의 때문에 (테스트되지 않은) 같은 :

    따라서 최신의 그리고 최고의 기능 중 일부 아직 단순히 API를 통해 잘 액세스 할 수 없습니다 - 드라이버는 현재 언어 MongoDB를 제공하는 기능 뒤에 조금 거의 항상. 나는이 그 사례 중 하나이며 문자열을 사용에 의존해야합니다 두렵다. 종류의 때문에 (테스트되지 않은) 같은 :

    AggregationOperation match = Aggregation.match(Criteria.where("dayOfWeek").is("SOME_VARIABLE_STRING_1"));
    AggregationOperation match2 = Aggregation.match(Criteria.where("deliveryZipCodeTimings").ne([]));
    String query = "{ $lookup: { from: 'deliveryZipCodeTiming', let: { location_id: '$fulfillmentLocationId' }, pipeline: [{ $match: { $expr: { $and: [ { $eq: ['$fulfillmentLocationId', '$$location_id']}, { $eq: ['$zipCode', 'SOME_VARIABLE_STRING_2']} ]} } }, { $project: { _id: 0, zipCode: 1, cutoffTime: 1 } }], as: 'deliveryZipCodeTimings' } }";
    Aggregation.newAggregation(match, (DBObject) JSON.parse(query), match2);
    
  2. ==============================

    2.@dnickless 의해 주어진 정보에 따라 구축, 나는이 문제를 해결 할 수 있었다. 나는 미래에 다른 사람을 돕는 희망에 완벽한 솔루션을 게시합니다.

    @dnickless 의해 주어진 정보에 따라 구축, 나는이 문제를 해결 할 수 있었다. 나는 미래에 다른 사람을 돕는 희망에 완벽한 솔루션을 게시합니다.

    나는 MongoDB의 드라이버를 사용하고 있습니다 : 3.6.4

    첫째, 나는 집계 작업에 사용되는 사용자 정의 JSON의 MongoDB의 쿼리를 전달할 수 있도록 사용자 정의 집계 작업 클래스를 작성했다. 이것은 제가 사용하고있는 드라이버 버전에서 지원되지 않는 $ 조회에서 파이프 라인을 사용할 수 있습니다.

    public class CustomProjectAggregationOperation implements AggregationOperation {
        private String jsonOperation;
    
        public CustomProjectAggregationOperation(String jsonOperation) {
            this.jsonOperation = jsonOperation;
        }
    
        @Override
        public Document toDocument(AggregationOperationContext aggregationOperationContext) {
            return aggregationOperationContext.getMappedObject(Document.parse(jsonOperation));
        }
    }
    

    이제 우리는 우리의 MongoDB의 스프링 구현으로 사용자 정의 JSON 쿼리를 전달할 수있는 능력을 가지고 있음을, 남아있는 모든은 TypedAggregation 쿼리에 해당 값을 연결하는 것입니다.

    public List<FulfillmentChannel> getFulfillmentChannels(
        String SOME_VARIABLE_STRING_1, 
        String SOME_VARIABLE_STRING_2) {
    
        AggregationOperation match = Aggregation.match(
                Criteria.where("dayOfWeek").is(SOME_VARIABLE_STRING_1));
        AggregationOperation match2 = Aggregation.match(
                Criteria.where("deliveryZipCodeTimings").ne(Collections.EMPTY_LIST));
        String query =
                "{ $lookup: { " +
                        "from: 'deliveryZipCodeTiming'," +
                        "let: { location_id: '$fulfillmentLocationId' }," +
                        "pipeline: [{" +
                        "$match: {$expr: {$and: [" +
                        "{ $eq: ['$fulfillmentLocationId', '$$location_id']}," +
                        "{ $eq: ['$zipCode', '" + SOME_VARIABLE_STRING_2 + "']}]}}}," +
                        "{ $project: { _id: 0, zipCode: 1, cutoffTime: 1 } }]," +
                        "as: 'deliveryZipCodeTimings'}}";
    
        TypedAggregation<FulfillmentChannel> aggregation = Aggregation.newAggregation(
                FulfillmentChannel.class,
                match,
                new CustomProjectAggregationOperation(query),
                match2
        );
    
        AggregationResults<FulfillmentChannel> results = 
            mongoTemplate.aggregate(aggregation, FulfillmentChannel.class);
        return results.getMappedResults();
    }
    
  3. from https://stackoverflow.com/questions/51107626/spring-data-mongodb-lookup-with-pipeline-aggregation by cc-by-sa and MIT license