MongoDB: criteria queryservice #30445
ldaloia-dev
started this conversation in
Show and tell
Replies: 1 comment
-
Below is the link to a public repository where I’ve pushed some changes to better illustrate what I mean. Key points:
@Document(collection = "dummy")
@SuppressWarnings("common-java:DuplicatedBlocks")
public class Dummy implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String id;
@Field("name")
private String name;
@Field("description")
private String description;
@DBRef
@Field("foo")
@JsonIgnoreProperties(value = { "dummy" }, allowSetters = true)
private Set<Foo> foos = new HashSet<>();
... @Document(collection = "foo")
@SuppressWarnings("common-java:DuplicatedBlocks")
public class Foo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String id;
@NotNull
@Field("name")
private String name;
@Field("description")
private String description;
@Field("start")
private Instant start;
@DBRef
@Field("dummy")
@JsonIgnoreProperties(value = { "foos" }, allowSetters = true)
private Dummy dummy;
...
@Transactional(readOnly = true)
public abstract class QueryServiceMongoDB {
protected <X> Criteria buildCriteria(Filter<X> filter, String field) {
if (filter.getEquals() != null) {
return equalsCriteria(field, filter.getEquals());
} else if (filter.getIn() != null) {
return valueIn(field, filter.getIn());
} else if (filter.getNotIn() != null) {
return valueNotIn(field, filter.getNotIn());
} else if (filter.getNotEquals() != null) {
return notEqualsCriteria(field, filter.getNotEquals());
} else if (filter.getSpecified() != null) {
return byFieldSpecified(field, filter.getSpecified());
}
return null;
}
protected <X> Criteria equalsCriteria(String field, final X value) {
return Criteria.where(field).is(value);
}
protected <X> Criteria valueIn(String field, final Collection<X> values) {
return Criteria.where(field).in(values);
}
protected <X> Criteria valueNotIn(String field, final X value) {
return Criteria.where(field).nin(value);
}
protected <X> Criteria notEqualsCriteria(String field, final X value) {
return Criteria.where(field).ne(value);
}
protected Criteria byFieldSpecified(String field, final boolean specified) {
return Criteria.where(field).exists(specified);
}
protected <X extends Comparable<? super X>> List<Criteria> buildRangeCriteria(RangeFilter<X> filter, String field) {
return buildCriteria(filter, field);
}
protected <X extends Comparable<? super X>> List<Criteria> buildCriteria(RangeFilter<X> filter, String field) {
if (filter.getEquals() != null) {
return Arrays.asList(equalsCriteria(field, filter.getEquals()));
} else if (filter.getIn() != null) {
return Arrays.asList(valueIn(field, filter.getIn()));
}
List<Criteria> result = new ArrayList<>();
if (filter.getSpecified() != null) {
result.add(byFieldSpecified(field, filter.getSpecified()));
}
if (filter.getNotEquals() != null) {
result.add(notEqualsCriteria(field, filter.getNotEquals()));
}
if (filter.getNotIn() != null) {
result.add(valueNotIn(field, filter.getNotIn()));
}
if (filter.getGreaterThan() != null) {
result.add(greaterThan(field, filter.getGreaterThan()));
}
if (filter.getGreaterThanOrEqual() != null) {
result.add(greaterThanOrEqualTo(field, filter.getGreaterThanOrEqual()));
}
if (filter.getLessThan() != null) {
result.add(lessThan(field, filter.getLessThan()));
}
if (filter.getLessThanOrEqual() != null) {
result.add(lessThanOrEqualTo(field, filter.getLessThanOrEqual()));
}
return result;
}
protected <X extends Comparable<? super X>> Criteria greaterThan(String field, final X value) {
return Criteria.where(field).gt(value);
}
protected <X extends Comparable<? super X>> Criteria greaterThanOrEqualTo(String field, final X value) {
return Criteria.where(field).gte(value);
}
protected <X extends Comparable<? super X>> Criteria lessThan(String field, final X value) {
return Criteria.where(field).lt(value);
}
protected <X extends Comparable<? super X>> Criteria lessThanOrEqualTo(String field, final X value) {
return Criteria.where(field).lte(value);
}
protected Criteria buildStringCriteria(StringFilter filter, String field) {
return buildCriteria(filter, field);
}
protected Criteria buildCriteria(StringFilter filter, String field) {
if (filter.getEquals() != null) {
return equalsCriteria(field, filter.getEquals());
} else if (filter.getIn() != null) {
return valueIn(field, filter.getIn());
} else if (filter.getNotIn() != null) {
return valueNotIn(field, filter.getNotIn());
} else if (filter.getContains() != null) {
return containSpecification(field, filter.getContains());
} else if (filter.getDoesNotContain() != null) {
return doesNotContainSpecification(field, filter.getDoesNotContain());
} else if (filter.getNotEquals() != null) {
return notEqualsCriteria(field, filter.getNotEquals());
} else if (filter.getSpecified() != null) {
return byFieldSpecified(field, filter.getSpecified());
}
return null;
}
protected Criteria containSpecification(String field, final String value) {
return Criteria.where(field).regex(value);
}
protected Criteria doesNotContainSpecification(String field, String value) {
return Criteria.where(field).not().regex(value);
}
protected Criteria buildReferringEntitySpecification(Filter<?> filter, String... path) {
return buildCriteria(filter, String.join(".", path));
}
}
@Service
@Transactional(readOnly = true)
public class DummyQueryService extends QueryServiceMongoDB {
private final Logger LOG = LoggerFactory.getLogger(DummyQueryService.class);
private final MongoTemplate mongoTemplate;
private final DummyMapper dummyMapper;
public DummyQueryService(MongoTemplate mongoTemplate, DummyMapper dummyMapper) {
this.mongoTemplate = mongoTemplate;
this.dummyMapper = dummyMapper;
}
/**
* Return a {@link Page} of {@link DummyDTO} which matches the criteria from the database.
* @param criteria The object which holds all the filters, which the entities should match.
* @param page The page, which should be returned.
* @return the matching entities.
*/
@Transactional(readOnly = true)
public Page<DummyDTO> findByCriteria(DummyCriteria criteria, Pageable page) {
LOG.debug("find by criteria : {}, page: {}", criteria, page);
final Query query = createQuery(criteria, null);
List<DummyDTO> result = mongoTemplate.find(query, Dummy.class).stream().map(dummyMapper::toDto).collect(Collectors.toList());
return PageableExecutionUtils.getPage(result, page, () -> countByCriteria(criteria));
}
/**
* Return the number of matching entities in the database.
* @param criteria The object which holds all the filters, which the entities should match.
* @return the number of matching entities.
*/
@Transactional(readOnly = true)
public long countByCriteria(DummyCriteria criteria) {
LOG.debug("count by criteria : {}", criteria);
final Query query = createQuery(criteria, null);
return mongoTemplate.count(query, Dummy.class);
}
/**
* Function to convert {@link DummyCriteria} to a {@link Query}
* @param criteria The object which holds all the filters, which the entities should match.
* @return the matching {@link Query} of the entity.
*/
protected Query createQuery(DummyCriteria criteria, Pageable page) {
List<Criteria> and = new ArrayList<>();
Query query;
if (criteria != null) {
if (criteria.getId() != null) {
and.add(buildStringCriteria(criteria.getId(), "id"));
}
if (criteria.getName() != null) {
and.add(buildStringCriteria(criteria.getName(), "name"));
}
if (criteria.getDescription() != null) {
and.add(buildStringCriteria(criteria.getDescription(), "description"));
}
if (criteria.getFooId() != null) {
and.add(buildReferringEntitySpecification(criteria.getFooId(), "foos", "id"));
}
query = new Query(and.isEmpty() ? new Criteria() : new Criteria().andOperator(and));
if (page != null) {
query.with(page);
}
return query;
}
return new Query();
}
}
Could these adjustments be automated by the generator, or is there a specific reason why they are not correct or not necessary? |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Is there a specific reason why, when generating a JHipster app with MongoDB, unlike with SQL, a QueryService is not configured for the entity in order to apply filters using criteria during the search phase?
Beta Was this translation helpful? Give feedback.
All reactions