"now" 和给定日期之间的差异

Difference between "now" and a given date

我需要检索集合中的所有文档,new ISODate() 和文档的日期字段之间的差异应大于给定参数。

我可以通过查询在 mongo shell 上执行此操作:

db.getCollection('tb_registered_app').aggregate(
[ 
    { 
        $project: { 
            difference: { $subtract: [ new ISODate(), "$ping_date" ] } 
        } 
    } 
    , 
    {
        $match: {difference: { "$gte": 300000}}
    }
]
)

我正在尝试使用 Spring 数据 MongoDB 执行相同的查询,代码为:

public List<RegisteredApp> getTimedOut(long timeout) {
        return mongoTemplate.aggregate(newAggregation(project().andExpression("new ISODate() - ping_date").as("difference"), match(where("difference").gte(timeout))), RegisteredApp.class, RegisteredApp.class).getMappedResults();
}

但我总是遇到异常:

org.springframework.expression.spel.SpelEvaluationException: EL1003E: A problem occurred whilst attempting to construct an object of type 'ISODate' using arguments '()'
    at org.springframework.expression.spel.ast.ConstructorReference.findExecutorForConstructor(ConstructorReference.java:199)
    at org.springframework.expression.spel.ast.ConstructorReference.createNewInstance(ConstructorReference.java:158)
    at org.springframework.expression.spel.ast.ConstructorReference.getValueInternal(ConstructorReference.java:100)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:109)
    at org.springframework.data.mongodb.core.spel.ExpressionNode.getValue(ExpressionNode.java:155)
    at org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer$ValueRetrievingNodeConversion.convert(SpelExpressionTransformer.java:621)
    at org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.transform(SpelExpressionTransformer.java:113)
    at org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.transform(SpelExpressionTransformer.java:58)
    at org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer$ExpressionNodeConversion.transform(SpelExpressionTransformer.java:215)
    at org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer$ExpressionNodeConversion.transform(SpelExpressionTransformer.java:205)
    at org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer$OperatorNodeConversion.convert(SpelExpressionTransformer.java:257)
    at org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.transform(SpelExpressionTransformer.java:113)
    at org.springframework.data.mongodb.core.aggregation.SpelExpressionTransformer.transform(SpelExpressionTransformer.java:105)
    at org.springframework.data.mongodb.core.aggregation.ProjectionOperation$ExpressionProjectionOperationBuilder$ExpressionProjection.toMongoExpression(ProjectionOperation.java:376)
    at org.springframework.data.mongodb.core.aggregation.ProjectionOperation$ExpressionProjectionOperationBuilder$ExpressionProjection.toDocument(ProjectionOperation.java:371)
    at org.springframework.data.mongodb.core.aggregation.ProjectionOperation.toDocument(ProjectionOperation.java:208)
    at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:55)
    at org.springframework.data.mongodb.core.aggregation.Aggregation.toPipeline(Aggregation.java:645)
    at org.springframework.data.mongodb.core.AggregationUtil.createPipeline(AggregationUtil.java:92)
    at org.springframework.data.mongodb.core.MongoTemplate.doAggregate(MongoTemplate.java:2095)
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:2071)
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1961)
    at br.com.santander.snapi.collectors.repository.impl.RegisteredAppRepositoryImpl.getTimedOut(RegisteredAppRepositoryImpl.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359)
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke(RepositoryFactorySupport.java:595)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy92.getTimedOut(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy92.getTimedOut(Unknown Source)
    at br.com.santander.snapi.collectors.service.impl.RegisteredAppServiceImpl.getTimedOutApps(RegisteredAppServiceImpl.java:40)
    at br.com.santander.snapi.collectors.scheduler.RegisteredAppScheduler.removeRegisteredApp(RegisteredAppScheduler.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.expression.AccessException: Failed to resolve constructor
    at org.springframework.expression.spel.support.ReflectiveConstructorResolver.resolve(ReflectiveConstructorResolver.java:115)
    at org.springframework.expression.spel.ast.ConstructorReference.findExecutorForConstructor(ConstructorReference.java:191)
    ... 68 common frames omitted
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1005E: Type cannot be found 'ISODate'
    at org.springframework.expression.spel.support.StandardTypeLocator.findType(StandardTypeLocator.java:117)
    at org.springframework.expression.spel.support.ReflectiveConstructorResolver.resolve(ReflectiveConstructorResolver.java:59)
    ... 69 common frames omitted

知道我做错了什么吗?

试试这个:

String jsonExpression = "{\"$subtract\":[new ISODate(),\"$ping_date\"]}";
AggregationOperation project = Aggregation.project().and(context -> context.getMappedObject(Document.parse(jsonExpression))).as("difference");
AggregationOperation match = Aggregation.match(Criteria.where("difference").gte("timeout"));

List<AggregationOperation> aggOps = new ArrayList<>();
aggOps.add(project);
aggOps.add(match);
Aggregation aggregation = Aggregation.newAggregation(aggOps);
return mongoTemplate.aggregate(aggregation, RegisteredApp.class, RegisteredApp.class).getMappedResults();

基本上,您可以使用此将 javascript/JSON 查询转换为 spring mongo 模板表单。您还可以查看 org.springframework.data.mongodb.core.aggregation 包中的 ArithmeticOperators.Subtract。

我写的这段代码有点冗长,您可以在不创建列表和所有其他内容的情况下执行相同的操作,就像您提出的问题一样。