I am using spring boot and mongodb for my project. I faced a problem with a property _id in my repository class. Before executing this query which is generated by my repositoryImpl class, I executed generated query in mongodb and it works fine.
If you change _id to id in java code, the PropertyReferenceException will disappear but the query stops working properly. It means that the underscore is must be presented here.
Can you help me, pls?
Intellij idea console log:
org.springframework.data.mapping.PropertyReferenceException: No property _id found for type Payment! Did you mean 'paid','id'?
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:77)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReference(TypeBasedAggregationOperationContext.java:83)
at org.springframework.data.mongodb.core.aggregation.InheritingExposedFieldsAggregationOperationContext.resolveExposedField(InheritingExposedFieldsAggregationOperationContext.java:59)
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:94)
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:71)
at org.springframework.data.mongodb.core.aggregation.GroupOperation.toDBObject(GroupOperation.java:392)
at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDBObject(AggregationOperationRenderer.java:56)
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:580)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1570)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1499)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1488)
at com.uzbekinvest.hayot.repository.PaymentRepositoryImpl.findAllTaxpayerIds(PaymentRepositoryImpl.java:137)
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.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:504)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:479)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy149.findAllTaxpayerIds(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:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy149.findAllTaxpayerIds(Unknown Source)
at com.uzbekinvest.hayot.service.CashFlowService.parse(CashFlowService.java:238)
at com.uzbekinvest.hayot.service.CashFlowService.read(CashFlowService.java:197)
at com.uzbekinvest.hayot.service.CashFlowService.save(CashFlowService.java:127)
at com.uzbekinvest.hayot.service.CashFlowService$$FastClassBySpringCGLIB$$3fca468f.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at com.uzbekinvest.hayot.aop.logging.LoggingAspect.logAround(LoggingAspect.java:85)
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.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.uzbekinvest.hayot.service.CashFlowService$$EnhancerBySpringCGLIB$$97e0b255.save(<generated>)
at com.uzbekinvest.hayot.web.rest.CashFlowResource.upload(CashFlowResource.java:158)
at com.uzbekinvest.hayot.web.rest.CashFlowResource$$FastClassBySpringCGLIB$$3bcfdc83.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at com.uzbekinvest.hayot.aop.logging.LoggingAspect.logAround(LoggingAspect.java:85)
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.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:48)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:34)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.uzbekinvest.hayot.web.rest.CashFlowResource$$EnhancerBySpringCGLIB$$edd4ccb1.upload(<generated>)
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.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:111)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at com.hazelcast.web.WebFilter.doFilter(WebFilter.java:373)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:155)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at com.uzbekinvest.hayot.security.jwt.JWTFilter.doFilter(JWTFilter.java:36)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
Payment Class
package com.uzbekinvest.hayot.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
* A Payment.
*/
@Document(collection = "payment")
public class Payment implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String id;
@NotNull
@DecimalMin(value = "0")
@Field("amount")
private double amount;
@NotNull
@Field("start_date")
private LocalDate startDate;
@NotNull
@Field("end_date")
private LocalDate endDate;
@Field("loan")
private Loan loan;
@Field("policy")
private Policy policy;
@Field("payment_details")
private Set<PaymentDetail> paymentDetails = new HashSet<>();
@Field("paid")
private double paid;
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getAmount() {
return amount;
}
public Payment amount(double amount) {
this.amount = amount;
return this;
}
public void setAmount(double amount) {
this.amount = amount;
}
public LocalDate getStartDate() {
return startDate;
}
public Payment startDate(LocalDate startDate) {
this.startDate = startDate;
return this;
}
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
public LocalDate getEndDate() {
return endDate;
}
public Payment endDate(LocalDate endDate) {
this.endDate = endDate;
return this;
}
public Loan getLoan() {
return loan;
}
public void setLoan(Loan loan) {
this.loan = loan;
}
public Policy getPolicy() {
return policy;
}
public void setPolicy(Policy policy) {
this.policy = policy;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
public double getPaid() {
return paid;
}
public void addPayment(double paid) {
this.paid += paid;
this.amount -= paid;
}
public void setPaid(double paid) {
this.paid = paid;
}
public Set<PaymentDetail> getPaymentDetails() {
return paymentDetails;
}
public void setPaymentDetails(Set<PaymentDetail> paymentDetails) {
this.paymentDetails = paymentDetails;
}
public void addPaymentDetail(PaymentDetail paymentDetail) {
this.paymentDetails.add(paymentDetail);
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Payment payment = (Payment) o;
if (payment.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), payment.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public String toString() {
return "Payment{" +
"id=" + getId() +
", amount='" + getAmount() + "'" +
", startDate='" + getStartDate() + "'" +
", endDate='" + getEndDate() + "'" +
"}";
}
}
PaymentRepository class
package com.uzbekinvest.hayot.repository;
import com.uzbekinvest.hayot.domain.Payment;
import org.springframework.security.access.method.P;
import org.springframework.stereotype.Repository;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.time.Instant;
import java.util.List;
/**
* Spring Data MongoDB repository for the Payment entity.
*/
@SuppressWarnings("unused")
@Repository
public interface PaymentRepository extends MongoRepository<Payment, String>, PaymentRepositoryCustom {
List<Payment> findByAmount(double amount);
List<Payment> findByStartDate(Instant startDate);
List<Payment> findByEndDate(Instant endDate);
}
PaymentRepositoryImpl class
package com.uzbekinvest.hayot.repository;
import ch.qos.logback.core.util.AggregationType;
import com.hazelcast.mapreduce.aggregation.Aggregations;
import com.hazelcast.util.StringUtil;
import com.mongodb.AggregationOptions;
import com.mongodb.BasicDBObject;
import com.mongodb.client.AggregateIterable;
import com.uzbekinvest.hayot.domain.Payment;
import com.uzbekinvest.hayot.domain.PaymentDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static java.util.Arrays.asList;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
public class PaymentRepositoryImpl implements PaymentRepositoryCustom {
@Autowired
MongoTemplate mongoTemplate;
@Override
public List<Payment> findAllTaxpayerIds(String taxpayerId) {
GroupOperation groupBy =
group("_id")
.first("amount").as("amount")
.sum("paymentDetails.paid").as("totalPaid");
MatchOperation taxpayerIdMatch = Aggregation.match(new Criteria()
.orOperator(
new Criteria("policy.organization.taxpayer_id").is(taxpayerId),
new Criteria("policy.user.taxpayer_id").is(taxpayerId)
));
// ProjectionOperation projection = project().andExpression("id");
// SortOperation sortByStartDateAsc = sort(new Sort(Sort.Direction.ASC, "startDate"));
Aggregation aggregation = newAggregation(
Payment.class,
taxpayerIdMatch,
unwind("paymentDetails"),
groupBy,
// project("id", "amount", "totalPaid"),
new RedactAggregationOperation(
new BasicDBObject(
"$redact",
new BasicDBObject(
"$cond", new BasicDBObject().append("if", new BasicDBObject(
"$gt", Arrays.asList("$amount", "$totalPaid")
))
.append("then", "$$KEEP")
.append("else", "$$PRUNE")
)
)
)
);
AggregationResults<Payment> aggregationResults = mongoTemplate.aggregate(
(TypedAggregation<Payment>) aggregation, Payment.class
);
return aggregationResults.getMappedResults();
}
private Criteria createMatchCriteria(String name, String value) {
return Criteria
.where(name)
.regex(Pattern.compile(value, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE));
}
}
Mongodb query:
{ "aggregate" : "__collection__" , "pipeline" : [
{ "$match" :
{ "$or" : [
{ "policy.organization.taxpayer_id" : "201122919"} ,
{ "policy.user.taxpayer_id" : "201122919"}]}} ,
{ "$unwind" : "$paymentDetails"} ,
{ "$group" : {
"_id" : "$_id" ,
"amount" : { "$first" : "$amount"} ,
"totalPaid" : { "$sum" : "$paymentDetails.paid"}
}} ,
{ "$redact" :
{ "$cond" : {
"if" : {
"$gt" : [ "$amount" , "$totalPaid"]} ,
"then" : "$$KEEP" ,
"else" : "$$PRUNE"}
}
}
]}