'Objectify - can we set a startAt(cursor) for QueryKeys? Or how to iterate over many Keys query?
I'm trying to iterate over 1000 keys of an entity at a time using this code but unlike Query, QueryKeys does not have a startAt() method for me to set it's cursor:
QueryKeys<Car> queryKeys = ofy().load().type(Car.class)
.limit(1000)
.keys();
// queryKeys has no startAt()
queryKeys = queryKeys.startAt(cursor)
Is there a way to loop through keys with QueryKeys just like Query?
The reason I want to loop through keys is that I need to delete those entities from the Datastore. I might be deleting 100k - 1 million entities of a single entity type and wanted to do it in chunks because I am afraid that loading that many keys may slow things down too much or maybe error out somehow.
Solution 1:[1]
If you delete a page synchronously, there's not need for pagination:
public void deleteAllEntities() {
boolean continueDeletionLoop = true;
while (continueDeletionLoop) {
QueryKeys<Car> queryKeys = objectify.get().load().type(Car.class)
.limit(1000)
.keys();
if (queryKeys.list().isEmpty()) {
continueDeletionLoop = false;
} else {
objectify.get().delete().keys(queryKeys).now();
}
}
}
Solution 2:[2]
You'll want to set the cursor before calling keys, e.g. objectify.get().load().type(Car.class).setStartCursor(...).limit(1000).keys().
Also, you are best to use the cursor from the previous query instead of relying on starting the query again to avoid skipping over tombstones as noted at https://cloud.google.com/datastore/docs/best-practices#deletions .
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | vpriesner |
| Solution 2 | Jim Morrison |
