弹簧数据mongo:比较同一文档中的两个日期

发布于 2025-02-11 05:02:55 字数 4190 浏览 0 评论 0原文

我正在使用的文档的简要概述:

@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Data
@SuperBuilder(toBuilder = true)
public class BreachBrand {

  @Id
  private String id;

  @CreatedDate
  @Field("created_date")
  @DiffIgnore
  private Instant createdDate;

  @LastModifiedDate
  @Field("last_modified_date")
  @DiffIgnore
  private Instant lastModifiedDate;
}

我要做的是将LastModifieddate与CreateDate进行比较。因此,我创建了一个标准对象这样的对象:

criteria.add(Criteria.where("last_modified_date").gt("ISODate('created_date')"));

我也尝试过:

criteria.add(Criteria.where("last_modified_date").gt("created_date"));

然后在聚合对象的匹配操作中使用。使用第一个标准代码代码段,汇总如下所示:

{ "aggregate" : "__collection__", "pipeline" : [{ "$lookup" : { "from" : "brands", "localField" : "brand_dfp_id", "foreignField" : "dfp_id", "as" : "brand"}}, { "$match" : { "$and" : [{ "last_modified_date" : { "$gt" : "ISODate('created_date')"}}]}}, { "$sort" : { "date" : -1}}, { "$skip" : 0}, { "$limit" : 25}], "allowDiskUse" : true, "collation" : { "locale" : "en", "strength" : 1}}

蒙古特板对象执行汇总方法,但没有错误,但没有返回记录。

我怀疑GT(对象O)方法期望的对象是用于比较的实际值。当我使用实际日期时,一切都很好:

criteria.add(Criteria.where("last_modified_date").gt(Instant.parse("2019-05-18T17:07:25.333+00:00")));

作为有趣的作品,在Mongoshell中进行的工作:以下

db.breaches.find({$where: "this.last_modified_date>this.created_date"}).pretty();

作品在Compass中的作品(但导出到语言按钮不会显示输出):

/**
 * $match operation 
 */
{
  last_modified_date: {$gt: ISODate('created_date')}
}

编辑:编辑: 看来我需要使用投影来确定last_modified_date是否大于创建的日期。我把这个在指南针中起作用:

[{
    $project: {
        greater: {
            $gt: [
                '$last_modified_date',
                '$created_date'
            ]
        },
        doc: '$$ROOT'
    }
}, {
    $match: {
        greater: true
    }
}]

我正在将其移动到一个投影中:

ProjectionOperation projectionOperation = project("last_modified_date", "created_date").andExpression("$gt", "$last_modified_date", "$created_date").as("greater");

我也尝试过:

ProjectionOperation projectionOperation = project("last_modified_date", "created_date").andExpression("$gt", Arrays.asList("$last_modified_date", "$created_date")).as("greater");

创建聚合时会导致例外:

Aggregation aggregation =  newAggregation(
lookup("brands", "brand_dfp_id", "dfp_id", "brand"),
projectionOperation,
matchOperation, //Criteria.where("greater").is(true)
sortOperation,
skipOperation,
limitOperation
)
.withOptions(AggregationOptions.builder()
.allowDiskUse(true)
.collation(Collation.of("en").strength(Collation.ComparisonLevel.primary())).build());

异常:

java.lang.IllegalArgumentException: Invalid reference 'date'!
    at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:114)
    at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:86)
    at org.springframework.data.mongodb.core.aggregation.SortOperation.toDocument(SortOperation.java:74)
    at org.springframework.data.mongodb.core.aggregation.AggregationOperation.toPipelineStages(AggregationOperation.java:55)
    at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:56)
    at org.springframework.data.mongodb.core.aggregation.AggregationPipeline.toDocuments(AggregationPipeline.java:77)
    at org.springframework.data.mongodb.core.aggregation.Aggregation.toPipeline(Aggregation.java:705)
    at org.springframework.data.mongodb.core.AggregationUtil.createPipeline(AggregationUtil.java:95)
    at org.springframework.data.mongodb.core.MongoTemplate.doAggregate(MongoTemplate.java:2118)
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:2093)
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1992)

A brief overview of the document I am working with:

@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Data
@SuperBuilder(toBuilder = true)
public class BreachBrand {

  @Id
  private String id;

  @CreatedDate
  @Field("created_date")
  @DiffIgnore
  private Instant createdDate;

  @LastModifiedDate
  @Field("last_modified_date")
  @DiffIgnore
  private Instant lastModifiedDate;
}

What I am trying to do is compare the lastModifiedDate to the createdDate. So I created a criteria object like so:

criteria.add(Criteria.where("last_modified_date").gt("ISODate('created_date')"));

I've also tried:

criteria.add(Criteria.where("last_modified_date").gt("created_date"));

which is then used in the match operation of an Aggregation object. Using the first criteria code snippet, the aggregation looks like this:

{ "aggregate" : "__collection__", "pipeline" : [{ "$lookup" : { "from" : "brands", "localField" : "brand_dfp_id", "foreignField" : "dfp_id", "as" : "brand"}}, { "$match" : { "$and" : [{ "last_modified_date" : { "$gt" : "ISODate('created_date')"}}]}}, { "$sort" : { "date" : -1}}, { "$skip" : 0}, { "$limit" : 25}], "allowDiskUse" : true, "collation" : { "locale" : "en", "strength" : 1}}

The mongoTemplate object executes the aggregate method w/o error but no records are returned.

I'm suspecting that the gt(Object o) method is expecting an object that is an actual value to use to compare against. All is good when I use an actual date:

criteria.add(Criteria.where("last_modified_date").gt(Instant.parse("2019-05-18T17:07:25.333+00:00")));

As an interesting aside the following works in mongoshell:

db.breaches.find({$where: "this.last_modified_date>this.created_date"}).pretty();

And the following works in Compass (but the export to language button will not display the output):

/**
 * $match operation 
 */
{
  last_modified_date: {$gt: ISODate('created_date')}
}

EDIT:
It appears I need to use a projection to determine if last_modified_date is greater than created date. I got this to work in compass:

[{
    $project: {
        greater: {
            $gt: [
                '$last_modified_date',
                '$created_date'
            ]
        },
        doc: '$ROOT'
    }
}, {
    $match: {
        greater: true
    }
}]

I'm having issues moving that into a projection though:

ProjectionOperation projectionOperation = project("last_modified_date", "created_date").andExpression("$gt", "$last_modified_date", "$created_date").as("greater");

I've also tried this:

ProjectionOperation projectionOperation = project("last_modified_date", "created_date").andExpression("$gt", Arrays.asList("$last_modified_date", "$created_date")).as("greater");

Results in an exception when creating the aggregation:

Aggregation aggregation =  newAggregation(
lookup("brands", "brand_dfp_id", "dfp_id", "brand"),
projectionOperation,
matchOperation, //Criteria.where("greater").is(true)
sortOperation,
skipOperation,
limitOperation
)
.withOptions(AggregationOptions.builder()
.allowDiskUse(true)
.collation(Collation.of("en").strength(Collation.ComparisonLevel.primary())).build());

exception:

java.lang.IllegalArgumentException: Invalid reference 'date'!
    at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:114)
    at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:86)
    at org.springframework.data.mongodb.core.aggregation.SortOperation.toDocument(SortOperation.java:74)
    at org.springframework.data.mongodb.core.aggregation.AggregationOperation.toPipelineStages(AggregationOperation.java:55)
    at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:56)
    at org.springframework.data.mongodb.core.aggregation.AggregationPipeline.toDocuments(AggregationPipeline.java:77)
    at org.springframework.data.mongodb.core.aggregation.Aggregation.toPipeline(Aggregation.java:705)
    at org.springframework.data.mongodb.core.AggregationUtil.createPipeline(AggregationUtil.java:95)
    at org.springframework.data.mongodb.core.MongoTemplate.doAggregate(MongoTemplate.java:2118)
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:2093)
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1992)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文