How to delete whole child entities by ancestor? - java

I'd like to reduce the number of queries to delete entities in Google App Engine.
I already know how to delete them with ancestor as below sequences.
Set an ancestor to query and fetch them.
Convert entities to keys and delete them using keys.
I'd like to remove first step.
My expectation is deleting all entities by ancestor without fetching as below.
DELETE FROM DS1 WHERE ancestor is "PARENT"
Is it possible?

There's no way to delete entities like that. You will need to access them by Key and batch delete.
Though there's a query type that better suits your needs, that is keys-only query, as you appear to be querying for full entities to delete them.

Related

Google App Engine update only one property of an entity that has many efficiently java

Looking for an efficient way to update only one property for an entity in GAE.
I know I can do a get by key, set a property and then put. But will the get not be very inefficient as it will load all properties? I have heard that you can make property specific queries but I was worried that once you load an entity with only say one or two out of its total properties, then put it back in the datastore that the properties not loaded in the query will be lost.
Any Advice?
PS also not sure about the query method because I heard direct gets are more efficient. Any possibility of a query that specifies simply the key and therefore will be just as efficient?
Afaik, entities are stored in a serialised form, so it makes no difference if you need one or all properties as they will all be loaded when entity's serialised form is loaded.
The "property specific queries" are actually called projection queries. They work on indexes only and only recreate "projected" fields you queried by. Since entities are only partially loaded (only projected fields are loaded) they should not be saved back to the Datastore.
Just use normal query and then multi-put. Yes, direct gets are more efficient (and less costly) but you need to have key/id of the entity.
If you need to update one property far more than others, you can move it into a separate, simpler entity that you can load and update independently of the main entity. This could be a child entity, or a separate one that shares key characteristics.
E.g.
Email <- main entity
Unread <- child entity of email
When the email is created, create an unread entity. When it's read, delete the unread entity. When searching for unread emails, perform a key-only query on the Unread entities, extract parent keys to find the Email entities you want.

Getting data from multiple tables without foreign keys in JPA 2.0

I've been stumbling upon followig issue for a couple of days now nad I can't make it to work. Here is the problem. I have four tables (A, B, C, D) which are not related to eachother via any kind of foreign key. Hovewer, they do have a column called, let's say, 'superId'.
The task is to take all the records from the A table, find records from the other ones with matching 'superId' (if they exist) and return them via JPA's constructor expression.
About JOINs. Since the tables have no relations, I can't do a left JOIN (or any other JOINs).
I tried to use MULTISELECT with a success, but it only works if I do an implicit joins with 'a.superId = b.superId'. This causes problems, since the three tables might not have matching records which will make the query to return empty set. This won't fly.
I have no other ideas, and this is crucial for my project to work. Please forgive me simple description of an issue - sending from my mobile.
You absolutely do not require the presence of a foreign key relationship to perform an arbitrary query in JPA2.
You can't "follow" a parent/child relationship, so you can't do your usual parentObject.childObject thing. You must instead use the Criteria API, or HQL, to construct a join.
See:
Using the Criteria API to Create Queries
Creating Queries Using the Java Persistence Query Language
JPQL language reference: joins

Objectify - how efficient is a key-only query filtered by ancestor?

I am trying to get all the children of a given parent entity efficiently. The only way to do that now is to use a query in objectify, which is not efficient because it bypasses the cache. Objectify-4 adds hybrid queries, which you can mimic in Objectify 3.x by issuing a key only query and then doing a batch get on those keys.
My question is how efficient is a key-only query that filters using an ancestor? Something like:
ofy.query(Car.class).ancestor(someKey).fetchKeys();
I don't want to get all keys for all "Cars" here, I only want "Cars" that belong to a specific parent.
Your query will get all Car entities which are children of given parent entity.
Billing docs state that keys-only query costs 1 read + 1 small operation per retrieved entity.

Checking if Entity exists in google app engine datastore.

What is the best/fastest way to check if an Entity exists in a google-app-engine datastore? For now I'm trying to get the entity by key and checking if the get() returns an error.
I don't know the process of getting an Entity on the datastore. Is there a faster way for doing only this check?
What you proposed would indeed be the fastest way to know if your entity exists. The only thing slowing you down is the time it takes to fetch and deserialize your entity. If your entity is large, this can slow you down.
IF this action (checking for existence) is a major bottleneck for you and you have large entities, you may want to roll your own system of checking by using two entities - first you would have your existing entity with data, and a second entity that either stores the reference to the real entity, or perhaps an empty entity where the key is just a variation on the original entity key that you can compute. You can check for existence quickly using the 2nd entity, and then fetch the first entity only if the data is necessary.
The better way I think would just be to design your keys such they you know there would not be duplicates, or that your operations are idempotent, so that even if an old entity was overwritten, it wouldn't matter.
com.google.appengine.api has been deprecated in favor of the App Engine GCS client.
Have you considered using a query? Guess-and-check is not a scalable way to find out of an entity exists in a data store. A query can be created to retrieve entities from the datastore that meet a specified set of conditions:
https://developers.google.com/appengine/docs/java/datastore/queries
EDIT:
What about the key-only query? Key-only queries run faster than queries that return complete entities. To return only the keys, use the Query.setKeysOnly() method.
new Query("Kind").addFilter(Entity.KEY_RESERVED_PROPERTY, FilterOperator.EQUAL, key).setKeysOnly();
Source: [1]: http://groups.google.com/group/google-appengine-java/browse_thread/thread/b1d1bb69f0635d46/0e2ba938fad3a543?pli=1
You could fetch using a List<Key> containing only one Key, that method returns a Map<Key, Entity> which you can check if it contains an actual value or null, for example:
Entity e = datastoreService.get(Arrays.asList(key)).get(key);
In general though I think it'd be easier to wrap the get() in a try/catch that returns null if the EntityNotFoundException is caught.

app engine query filter by 'id' range of entities, ignoring ancestor(s)

I have entities like these ones:
Entity [products(147)]
Entity [manufacturer(23)/products(131)]
Entity [manufacturer(17)/products(131)]
Now, I'm trying to find using a Query all the entities of kind 'products' which have an ID from 100 and up. Ones like the above 147 & 131.
The problem is that I don't know how to ask for these, "detaching" the ancestor from it in the query.
Tried these:
Not working:
SELECT __key__ FROM products WHERE ID >= 100
Partially working:
SELECT __key__ FROM products WHERE __key__ >= 100
This is how I insert the query filter:
query.addFilter("__key__", FilterOperator.GREATER_THAN_OR_EQUAL, KeyFactory.createKey("products", 100));
This partially working one gives the proper results ONLY for 'root' entities, i.e ones without an ancestor.
Any way to modify it so it ignore ancestor(s)? Thanks!
There's no built in way to do this, because this query is meaningless. IDs are allocated such that they are unique for a given kind and parent. You can't rely on IDs alone to uniquely identify an entity if it might have different parent entities, so it's pretty meaningless to query for a range of IDs regardless of parent.

Categories

Resources