I have a MongoDB (and for queries use Java Spring) database of persons which has unique ids. Let say that I have two ids and I want to obtain their persons. Something like this.
Query q = new Query();
Criteria c = new Criteria().orOperator(Criteria.where("id").is("1"),
Criteria.where("id").is("2"));
q.addCriteria(c);
operations.find(q, Person.class);
But this does not work becase I use "id" field two times. Any idea?
ops.find(query(where("id").in([1, 2]));
Related
I have created two entities in JPA, Listing and ItemType - these exist in a many-to-many relationship (Hibernate auto-generates a junction table). I'm trying to find the best way to create a query which accepts a dynamic list of item type Strings and returns the IDs of all listings which match the specified item types, but I am a recent initiate in JPA.
At present I'm using JpaRepository to create relatively simple queries. I've been trying to do this using CriteriaQuery but some close-but-not-quite answers I've read elsewhere seem to suggest that because this is in Spring, this may not be the best approach and that I should be handling this using the JpaRepository implementation itself. Does that seem reasonable?
I have a query which doesn't feel a million miles away (based on Baeldung's example and my reading on WikiBooks) but for starters I'm getting a Raw Type warning on the Join, not to mention that I'm unsure if this will run and I'm sure there's a better way of going about this.
public List<ListingDTO> getListingsByItemType(List<String> itemTypes) {
List<ListingDTO> listings = new ArrayList<>();
CriteriaQuery<Listing> criteriaQuery = criteriaBuilder.createQuery(Listing.class);
Root<Listing> listing = criteriaQuery.from(Listing.class);
//Here Be Warnings. This should be Join<?,?> but what goes in the diamond?
Join itemtype = listing.join("itemtype", JoinType.LEFT);
In<String> inClause = criteriaBuilder.in(itemtype.get("name"));
for (String itemType : itemTypes) {
inClause.value(itemType);
}
criteriaQuery.select(listing).where(inClause);
TypedQuery<Listing> query = entityManager.createQuery(criteriaQuery);
List<Listing> results = query.getResultList();
for (Listing result : results) {
listings.add(convertListingToDto(result));
}
return listings;
}
I'm trying to understand how best to pass in a dynamic list of names (the field in ItemType) and return a list of unique ids (the PK in Listing) where there is a row which matches in the junction table. Please let me know if I can provide any further information or assistance - I've gotten the sense that JPA and its handling of dynamic queries like this is part of its bread and butter!
The criteria API is useful when you need to dynamically create a query based on various... criteria.
All you need here is a static JPQL query:
select distinct listing from Listing listing
join listing.itemTypes itemType
where itemType.name in :itemTypes
Since you're using Spring-data-jpa, you just need to define a method and annotate it with #Query in your repository interface:
#Query("<the above query>")
List<Listing> findByItemTypes(List<String> itemTypes)
How do we find if any element of an array is part of another array in a query?
var followers = []; // Array of Parse User pointers
query.howTo("attending", followers); // attending is an array of User Pointers.
That is, the query should match if any one or more of the elements in followers exists in attending.
query.containsAll matches for all the elements. Is there something like query.containsSome ?
I was pretty sure you can query two arrays. Take a look into the docs to check better.
In case it doesn't, you can use compound queries.
For example, generate an array of queries, based on the array of followers. The [forEach] is a better idea in this case, but I'm supposing here a for loop.
var followers = []; //array of users
var mainQuery = new Parse.Query(YourOtherObject);
//for each one of followers
var orQuery = new Parse.Query(YourOtherObject);
orQuery.equalTo("attending", follower);
mainQuery = Parse.Query.or(mainQuery, orQuery);
This solution might not be performant if your followers areay is too big. But in any case, I still recommend using relations in this case, as you benefit from the inverse, and can get from the users query, where he is present as attending in the other Object.
for example i want to find age between 16 and 25 from a collection in mongoDB.
my query is..
Query query = new Query(Criteria.where("visibility").is(1)
.and("type").is("guide").and("age").gte(16).and("age").lte(25));
but it is giving exception. reason is mongo template do not support lte() and gte() with same column. so how can i handle it ? is their any solution ?
Try not to include an extra and("age") part in your criteria. What you need is this:
Query query = new Query(Criteria.where("visibility").is(1)
.and("type").is("guide").and("age").gte(16).lte(25));
Raven DB gave me this message
Method not supported: Contains
for this code :
using (var d = DataLayer.RavenDB.d.OpenSession())
{
foos = d.Query<Foo>().Where(foo => ids.Contains(foo.Id)).Skip(i * 10).Take(10).ToList();
}
how can I retrieve my list foos ?
It looks like you are trying to query multiple documents by id. Querying by Id is not recommended in Raven. Load them instead. There is an overload that takes multiple Ids.
foos = session.Load<Foo>(ids);
If this was some other property rather than Id, you would use item.In(list) rather than list.Contains(item).
if you want to load the documents based on the list of ids, go the solution suggested by Matt, performance wise Load() is the best approach.
but if you still wants to get it using Query (using some where contiions) change the code like this
using (var d = DataLayer.RavenDB.d.OpenSession())
{
foos = d.Query<Foo>()
.Where(foo => foo.Id.In<string>(ids))
.Skip(i * 10)
.Take(10).ToList();
}
i've got a really simple linq to entites statement :-
var query = (from q in Users.Include("UserHistory")
select q).Take(20);
works great ... except that, for each user .. the history can be n+1. Some users have 100's of UserHistory records.
So, can I restrict the the number of UserHistory records to .. 10 or 5 or whatever?
Do I need to use projections for this? Can it be done without projections?
You can't do this by using the include, but you can try this:
var query =
from user in Users
select new
{
user,
history = user.UserHistory.Take(20)
};
I'm not sure whether EF is able to create one single SQL query of of it.