【问题标题】:Make operations in $addField aggregation in Spring Data MongoDb 3.0.0在 Spring Data MongoDb 3.0.0 中的 $addField 聚合中进行操作
【发布时间】:2021-08-04 14:14:30
【问题描述】:

我尝试了不同的方法来使用 Spring Data Mongo Db 进行聚合,但它们都不适合我的目的:使用操作动态添加字段。

这是我的 mongoDB 聚合(它有效,我检查过):

db.getCollection("AquilaMaterial").aggregate(
[
    { 
        "$match" : { 
            "a.date" : { 
                "$gte" : ISODate("2021-08-01T00:00:00.000+0000"), 
                "$lte" : ISODate("2021-08-02T00:00:00.000+0000")
            }, 
            "a.line" : "TEST"
        }
    }, 
    { 
        "$addFields" : { 
            "time_dist" : { 
                "$abs" : [
                    { 
                        "$subtract" : [
                            "$a.date", 
                            ISODate("2021-08-01T11:52:00.000+0000")
                        ]
                    }
                ]
            }
        }
    }, 
    { 
        "$sort" : { 
            "time_dist" : 1.0
        }
    }, 
    { 
        "$limit" : 20.0
    }, 
    { 
        "$project" : { 
            "time_dist" : 0.0
        }
    }, 
    { 
        "$sort" : { 
            "a.date" : 1.0
        }
    }
])

所以,首先,我写了这段代码,但经过很长时间的等待,我得到了 javaHeapSpace:

@Aggregation(
    pipeline = "{ '$match' : { 'a.date' : { '$gte' : ?1, '$lte' : ?2}, 'a.line' : ?3"
        + "}}, { '$addFields' : { 'time_dist' : {'$abs'[{ '$subtract' : ['$a.date', ?0]}]}}}, {'$sort' : { "
        + "'time_dist' : 1}},{'$limit' : _sampleSize},{ '$project' : {'time_dist' : 0}},{'$sort' : {'a.date' : 1}}")
AggregationResults<MaterialEntity> findMaterialsInSequenceDate(final Date _date, final Date _dateFrom, final Date _dateTo,
    String _line, int _sampleSize);

我尝试手动编写它,但在我的情况下我无法弄清楚如何正确使用 addFieldsOperation。它执行如下操作:

public List<MaterialEntity> findMaterialsInSequenceDate(final Date _date, final Date _dateFrom, final Date _dateTo,
    final String _line, final int _sampleSize) {

    MatchOperation matchDateOp = Aggregation.match(Criteria.where("metalUnit.cuttingDate").gte(_dateFrom).lte(_dateTo));
    MatchOperation matchLineOp = Aggregation.match(Criteria.where("metalUnit.metalUnitReference.step.stepName").is(_line));
    AddFieldsOperation addFieldOp = Aggregation.addFields().addField("time_dist")
        .withValueOf(**DO_SOMETHING**).build();
    SortOperation sortOp = Aggregation.sort(Sort.Direction.ASC, "time_dist");
    LimitOperation limitOp = Aggregation.limit(_sampleSize);
    SortOperation sortOp2 = Aggregation.sort(Sort.Direction.ASC, "a.date");
    Aggregation agg = Aggregation.newAggregation(matchDateOp, matchLineOp, addFieldOp, sortOp, limitOp, sortOp2);

    AggregationResults<MaterialEntity> aggResults = mongoTemplate.aggregate(agg, "Material",
        MaterialEntity.class);
    return aggResults.getMappedResults();
}

此代码在没有 addedField(以及与之关联的排序)的情况下工作,但我得到的数据当然不好......

【问题讨论】:

  • 这个执行的时候,你可以在控制台看到执行的聚合...你对比过吗?

标签: mongodb spring-data-mongodb spring-repositories


【解决方案1】:

这可行,但我担心日期有偏差,因为没有使用正确的时区。有什么想法可以改进吗? 公共列表 findMaterialsInSequenceDate(final Date _date, final Date _dateFrom, final Date _dateTo, final String _line, final int _sampleSize) {

    MatchOperation matchDateOp = Aggregation.match(Criteria.where("a.date").gte(_dateFrom).lte(_dateTo));
    MatchOperation matchLineOp = Aggregation.match(Criteria.where("a.line").is(_line));
    AddFieldsOperation addFieldDateTemp = Aggregation.addFields().addField("timeStampTemp").withValue(_date).build();
    AddFieldsOperation addFieldOp = Aggregation.addFields().addField("time_dist")
        .withValueOf(ArithmeticOperators.Abs.absoluteValueOf(Subtract.valueOf("timeStampTemp").subtract("a.date"))).build();
    SortOperation sortOp = Aggregation.sort(Sort.Direction.ASC, "time_dist");
    LimitOperation limitOp = Aggregation.limit(_sampleSize);
    SortOperation sortOp2 = Aggregation.sort(Sort.Direction.ASC, "metalUnit.cuttingDate");
    Aggregation agg = Aggregation.newAggregation(matchDateOp, matchLineOp, addFieldDateTemp, addFieldOp, sortOp, limitOp, sortOp2);

    AggregationResults<MaterialEntity> aggResults = mongoTemplate.aggregate(agg, "Material",
        MaterialEntity.class);
    return aggResults.getMappedResults();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 2020-07-27
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    相关资源
    最近更新 更多