Difference between “now” and a given date

最后都变了- 提交于 2019-12-12 21:03:24

问题


I need to retrieve all documents in a collection that the difference between new ISODate() and a date field of the document should be greater than a given parameter.

I can do this on mongo shell by the query:

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

I'm trying to use Spring Data MongoDB to execute the same query, with the code:

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();
}

but I'm always getting the exception:

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$3(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.access$301(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

Any idea what am I doing wrong?


回答1:


Try this:

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();

Basically, you can convert your javascript/JSON query to spring mongo template form by using this. You can also check out ArithmeticOperators.Subtract in org.springframework.data.mongodb.core.aggregation package.

I wrote this code a bit verbose, you can do the same without creating list and all other stuffs, as you had in question.



来源:https://stackoverflow.com/questions/57045748/difference-between-now-and-a-given-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!