I want to query the datastore using Objectify with orderBy Geopt to get the data sorted with closest position.
I tried filter
GeoPt geoPt = filterWrapper.getGeoPt();
Query.StContainsFilter geoFilter = new Query.StContainsFilter("location", new Query.GeoRegion.Circle(geoPt, 5000));
But it just filters the data and not sorting.
So is any other way to sort/order by Geopt in datastore with objectify
Related
This question already has answers here:
How to fetch all documents from a firebase collection where each document has some sub collection and in sub collection there is a document?
(2 answers)
Closed 6 months ago.
My data is stored in Firestore in below model.
My Problem is, I want to get schoolid of logged-in email id.
Data Model:
instituteData->schoolid->users->email->data
What I tried
const q = query(collection(db, "instituteData"), where("email", "==", "abc#gmail.com"));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
Screenshot of Data Structure
Screenshot of Data Structure
Firestore queries can only filter on data in the documents that they return. So unless the email field is. inside the school documents, your query won't work.
The common workarounds are to:
Replicate the email of each user in their school document, and using an array-contains query to then find the school.
Using a collection group query on all users collections to find the correct user(s), and then going up the ref.parent().parent() chain of the document snapshots to find the school for each result.
Also see:
firestore query document that have a collection contains a document
How to query Firestore subcollection's document's data?
How to fetch all documents from a firebase collection where each document has some sub collection and in sub collection there is a document?
As far as I know, there are no inner queries in firebase like we have in SQL, and your approach looks like the SQL table approach, clearly, your structure will not work well in firebase. You shouldn't make SQL-like structure in NoSQL, I learned this hard way.
one solution I can think of is to store the id of parent collections in child collection and all of their documents.
Basically, you are passing ids parent to all children. ¯\(ツ)/¯
In your case
you should store schoolId in all its students, then you can directly get that document with getDoc() query and schoolId will be there already.
Hope this helps 😁
I have a collection in Firebase's Cloud Firestore database with subcollections like so:
myCollection
doc1
statistics
doc1
doc2
doc3
doc2
statistics
doc1
doc2
doc3
statistics
doc1
doc2
doc3
doc4
doc4
statistics
and so on.
Based off of a query, I pull maybe doc1, doc2, and doc4 from the collection, for example. Now, for each of those, I need to query their respective subcollections for relevant statistics.
My solution in my AngularJS app so far has been:
/**
* Gets aggregate views for queried docs.
* #param {![firebase.firestore.DocumentSnapshot]} docs - the queried documents
*/
$scope.getTotalViews = (docs) => {
let promises = [];
docs.forEach(doc => {
promises.push($scope.getTotalDocumentViews(doc.id));
});
$q.all(promises).then(totalViewsArray => {
// TODO: Sum the array to get aggregate views for queried documents
// Only outputs some of the time
console.log(totalViewsArray);
});
};
/**
* Gets all view statistics from a given document's subcollection.
*/
$scope.getTotalDocumentViews = (id) => {
let deferred = $q.defer();
firebase.firestore().collection("myCollection").doc(id).collection("statistics").where("type", "==", "view").get().then(snapshot => {
deferred.resolve(snapshot.size);
});
return deferred.promise;
};
The problem I am running into is since there can be many documents that are returned by the query on myCollection, looping through all of these and querying their subcollections seems grossly inefficient. Not only that but, while the above code does succeed some of the time, a lot of the time it throws the error:
Uncaught (in promise) Error: transaction closed
I have also tried to perform the multiple subcollection queries in a transaction, but this has not worked as well since I am not retrieving just one doc, but rather querying for potentially hundreds from the subcollection.
How do I efficiently query the subcollections of some set of multiple documents?
I think the same applies here as to most other NoSQL databases (and definitely the Firebase Realtime Database): if you want to be able to efficiently get the count of something from the database, you should store that count as a property and update it continuously (in this case) views occur. Trying to read hundreds of documents just to determine their count isn't going to scale.
So consider adding a view_count property to each document, and increment that (likely with a transaction) as you record views.
I am trying to execute the below query using Objectify 5.1.8 :-
Query<Coupon> coupons = ObjectifyService.ofy().load().type(Coupon.class).filter("rewardPoints !=", "").project("code").distinct(true);
for (Coupon coupon : coupons) {
out.write(coupon.getCode());
}
It is giving me an error :
java.lang.IllegalArgumentException: Inequality filter on rewardPoints must also be a group by property when group by properties are set.
Basically, what I wish to achieve is to perform a filter and project query alongside the distinct query on an entity.
Please let me know if there is something wrong with the query.
Note: rewardPoints is Indexed.
I don't know about Objectify but in the Google App Engine Datastore a Projection query limits the returned results to just the column(s) specified. Using distinct is the same as grouping and from the error message, it looks like you need to add rewardPoints to the projection in order to use the inequality filter and distinct at the same time.
Looks like Josh was right. I changed the query and it worked perfectly.
Query<Coupon> coupons = ObjectifyService.ofy().load().type(Coupon.class).filter("rewardPoints !=", "").project("rewardPoints").project("code").distinct(true);
It would appear that Objectify does not support the Datastore's CompositeFilter. But objectify does take Filters. So for now how do I implement a composite AND filter in objectify? I am moving from Datanucleus and I need the query
"SELECT f.healthy FROM Food f WHERE f.fan = :userid AND flavor = : flavor";
So the type is Food.class and the fields are fan and flavor
You should create a composite filter and pass that to ofy query variant which accepts filter.
CompositeFilterOperator.and(
FilterOperator.EQUAL.of("f.fan", userId),
CompositeFilterOperator.or(
FilterOperator.EQUAL.of("flavor", flavor),
FilterOperator.EQUAL.of("color", color)));
However, implementing OR filters have its own side effects; for e.g. you can't use cursors.
Ref of above code: https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/Query.CompositeFilter
Queries are quite simple:
List<Food> foods = ofy().load().type(Food.class).filter("fan", xxx).filter("flavor", xxx).list();
make sure all fields you plan to filter/sort on are marked with #Index before persisting the entities.
I have documents in a collection that have an array of properties (1-400 different numeric values).
Now i want to get all documents of another collection that have one of these properties (these documents only have one property).
How can i do that, preferably in one call?
As MongoDB is no relational DBMS this isn't possible to achieve with only one call.
What you need to do is to first retrieve your document your want to use for your search. Upon you retrieved it, you're using that array stored in the document todo a $in query on the field for the other collection. So for the mongo shell this could be something like this:
var ar = db.coll1.findOne().numArray
db.coll2.find({b: { $in : ar }})