I am using MongoDB with Spring. I want to query the database by _id.
Currently I have this query:
Query q = new Query(Criteria.where("_id").is(someId).and("deleted").is(false));
But this is giving me StackOverflowError somehow. What's wrong with this query? Or what is a better way of doing this?
Create an explicit AND query instead of a chained one using the $and operator Criteria.andOperator() for all of the provided criteria as follows:
Query q = new Query(
new Criteria().andOperator(
Criteria.where("_id").is(someId),
Criteria.where("deleted").is("false")
)
);
This is normally used in instances where you can't use Criteria.and() to add multiple criteria into the same field, for example
Query q = new Query();
q.addCriteria(Criteria.where("age").lt(40).and("age").gt(10));
will throw an error, so a workaround would be to use Criteria.andOperator() as
Query q = new Query();
q.addCriteria(
Criteria.where("age").exists(true).andOperator(
Criteria.where("age").gt(10),
Criteria.where("age").lt(40)
)
);
Related
I'm trying to write a CriteriaQuery which will query latest observation for each city. City is defined by city_code field, while latest record is defined by observation_time field.
I can easily write it in a plain SQL, but I cant understand how to do it with jpa criteria api.
select distinct m.* from
(select city_code cc, max(observation_time) mo
from observations group by city_code) mx, observations m
where m.city_code = mx.cc and m.observation_time = mx.mo`
It is possible when You are open for loose efficiency.
So first let's transform our query to logical equivalent one:
select distinct m.* from observations m where
m.observation_time = (select max(inn. observation_time) from observations inn
where inn.city_code = m.city_code);
then let's translate it to JPA CriteriaQuery:
public List<Observation> maxForEveryWithSubquery() {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Observation> query = builder.createQuery(Observation.class);
Root<Observation> observation = query.from(Observation.class);
query.select(observation);
Subquery<LocalDateTime> subQuery = query.subquery(LocalDateTime.class);
Root<Observation> observationInner = subQuery.from(Observation.class);
subQuery.where(
builder.equal(
observation.get(Observation_.cityCode),
observationInner.get(Observation_.cityCode)
)
);
Subquery<LocalDateTime> subSelect = subQuery.select(builder.greatest(observationInner.get(Observation_.observationTime)));
query.where(
builder.equal(subSelect.getSelection(), observation.get(Observation_.observationTime))
);
TypedQuery<Observation> typedQuery = entityManager.createQuery(query);
return typedQuery.getResultList();
}
Unfortunately JPA does not support sub queries in FROM clause. You need to write a native query or use framework like FluentJPA.
How can I write this SQL query as a Hibernate JPA Criteria (with Restrictions, etc) in Java ?
SELECT q.*
FROM queue AS q
WHERE q.executed = false AND
q.queued_on = (SELECT min(queued_on) FROM queue WHERE item_id = q.item_id);
I only managed to write the first part like this:
getBaseCriteria()
.add(Restrictions.eq("executed", false))
// Missing Second Where Filter Here
.addOrder(Order.asc("queuedOn"))
.list();
Try to create a separate criteria instance for the subquery and simply add as another restriction as follows:
DetachedCriteria subCriteria = DetachedCriteria.forClass(Queue.class, "sub")
.add(Restrictions.eqProperty("sub.itemId","main.itemId"))
.setProjection(Projections.projectionList().add(Projections.min("sub.queuedOn")));
session.createCriteria(Queue.class, "main")
.add(Subqueries.propertyEq("main.queuedOn", subCriteria ));
.add(Restrictions.eq("main.executed", false));
.addOrder(Order.asc("main.queuedOn"))
.list();
Let´s see if somebody can help with this.
I want use Repository of Spring Data mongodb, and I want use Query annotation to filter the find by value A=10 or A=20
#Query("{A: 10, A:20}")
findById(int id);
Obiously "," try to make an AND, and I need an OR.
Any idea please?
Or if you are using a Criteria API
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("A").is(10),Criteria.where("B").is(20));
Query query = new Query(criteria);
mongoOps.find(query, <Yourclass>.class, "collectionName");
I think this might work
#Query("{'$or':[ {'A':10}, {'B':20} ] }")
You can use Spring Data MongoDB like this:
Query query = new Query();
query.addCriteria(
Criteria.where("").orOperator(
Criteria.where("A").is(10),
Criteria.where("B").is(20)
)
);
mongoTemplate.find(query, YourClazz.class, "CollectionName");
In addition to helloJava answer, If you already have query with other criteria's you can add orOperation directly on query.addCriteria as below.
query.addCriteria(new Criteria().orOperator(Criteria.where("fieldA").is(value),
Criteria.where("fieldB").is(value2)));
You can use the $in operator in Spring Java:
Criteria criteria = Criteria.where("field").in(listOfOptions);
You can use the $in operator for that. I don't know Java Spring, but given your example, the Query part should look like:
#Query("{A: {$in: [10, 20]}}")
Use Spring's BasicQuery:
DBObject queryCondition = new BasicDBObject();
BasicDBList values = new BasicDBList();
values.add(new BasicDBObject("A", 10));
values.add(new BasicDBObject("B", 20));
queryCondition.put("$or", values);
Query query = new BasicQuery(queryCondition);
mongoTemplate.find(query, clazz);
Query query = new Query();
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("category").is("your_Value_Category"),
Criteria.where("parentCategory").is("your_Value_ParentCategory"));
query.addCriteria(criteria);
mongoTemplate.find(query, YourPersistenceClass.class);
You can use Spring's Query structure:
Query query = new Query();
query.addCriteria(Criteria.where("id").is(10).orOperator(Criteria.where("id").is(20));
this.client.findOne(query, clazz);
Let´s see if somebody can help with this.
I want use Repository of Spring Data mongodb, and I want use Query annotation to filter the find by value A=10 or A=20
#Query("{A: 10, A:20}")
findById(int id);
Obiously "," try to make an AND, and I need an OR.
Any idea please?
Or if you are using a Criteria API
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("A").is(10),Criteria.where("B").is(20));
Query query = new Query(criteria);
mongoOps.find(query, <Yourclass>.class, "collectionName");
I think this might work
#Query("{'$or':[ {'A':10}, {'B':20} ] }")
You can use Spring Data MongoDB like this:
Query query = new Query();
query.addCriteria(
Criteria.where("").orOperator(
Criteria.where("A").is(10),
Criteria.where("B").is(20)
)
);
mongoTemplate.find(query, YourClazz.class, "CollectionName");
In addition to helloJava answer, If you already have query with other criteria's you can add orOperation directly on query.addCriteria as below.
query.addCriteria(new Criteria().orOperator(Criteria.where("fieldA").is(value),
Criteria.where("fieldB").is(value2)));
You can use the $in operator in Spring Java:
Criteria criteria = Criteria.where("field").in(listOfOptions);
You can use the $in operator for that. I don't know Java Spring, but given your example, the Query part should look like:
#Query("{A: {$in: [10, 20]}}")
Use Spring's BasicQuery:
DBObject queryCondition = new BasicDBObject();
BasicDBList values = new BasicDBList();
values.add(new BasicDBObject("A", 10));
values.add(new BasicDBObject("B", 20));
queryCondition.put("$or", values);
Query query = new BasicQuery(queryCondition);
mongoTemplate.find(query, clazz);
Query query = new Query();
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("category").is("your_Value_Category"),
Criteria.where("parentCategory").is("your_Value_ParentCategory"));
query.addCriteria(criteria);
mongoTemplate.find(query, YourPersistenceClass.class);
You can use Spring's Query structure:
Query query = new Query();
query.addCriteria(Criteria.where("id").is(10).orOperator(Criteria.where("id").is(20));
this.client.findOne(query, clazz);
How can I build a query in ORMLite so that I can use the orderBy function (using either the one with the raw string or the parametrized one) referencing an attribute of a different entity than the one of the dao I'm building the query from? My query is built like that:
// Inner query for performances
QueryBuilder<Performance, String> performancesQB = performanceDao.queryBuilder();
performancesQB.selectColumns("performance_id");
SelectArg performanceSelectArg = new SelectArg();
performancesQB.where().lt("date", performanceSelectArg);
// Outer query for Order objects, where the id matches in the performance_id
// from the inner query
QueryBuilder<Order, String> ordersQB = orderDao.queryBuilder();
ordersQB.where().isNull("user_id").and().in("performance_id", performancesQB);
ordersQB.orderByRaw("performances.date DESC");
pastOrdersQuery = ordersQB.prepare();
And the exception I'm getting whenever I try to execute this query is:
android.database.sqlite.SQLiteException: no such column: performances.date:,
while compiling: SELECT * FROM `orders` WHERE
(`user_id` IS NULL AND `performance_id` IN
(SELECT `performance_id` FROM `performances` WHERE `date` < ? ) )
ORDER BY performances.date DESC
The only solution I see here is writing a raw query myself using a JOIN instead of a nested select. May this be a good solution?
ORMLite now supports simple JOIN queries. Here the docs on the subject:
http://ormlite.com/docs/join-queries
So your query would now look something like:
QueryBuilder<Performance, String> performancesQB = performanceDao.queryBuilder();
SelectArg performanceSelectArg = new SelectArg();
performancesQB.where().lt("date", performanceSelectArg);
performancesQB.orderBy("date", false);
// query for Order objects, where the id matches
QueryBuilder<Order, String> ordersQB = orderDao.queryBuilder();
ordersQB.join(performancesQB).where().isNull("user_id");
pastOrdersQuery = ordersQB.prepare();