A common situation... you have some large entities, but sometimes you only need to retrieve a few of their fields.
SELECT name, email, phone, FROM CUSTOMER
SELECT * FROM CUSTOMER
Using GQL:
from google.appengine.ext import db proj = db.GqlQuery("SELECT content, author FROM Greeting")
Using Query:
from google.appengine.ext import db proj = db.Query(Greeting, projection=('content', 'author'))
You handle the results of these queries like a standard query.
Using NDB:
from google.appengine.ext import ndb greetings = Greeting.query().order(-Greeting.date).fetch( 20, projection=[Greeting.content, Greeting.author])
import com.google.appengine.api.datastore.PropertyProjection; import com.google.appengine.api.datastore.RawValue; Query proj = new Query("Greeting",guestbookKey); proj.addProjection(new PropertyProjection("user", User.class)); proj.addProjection(new PropertyProjection("date", Date.class));
SELECT A FROM kind WHERE A = 1
SELECT A FROM kind WHERE B = 1
or SELECT A FROM kind WHERE A > 1
SELECT A, B, C FROM Kind
Index(Kind, A, B, C)
index.yaml
or the Index Viewer panel in the admin console: what indexes are your existing queries using?SELECT * FROM Kind WHERE A > 1 ORDER BY A, B
Index(Kind, A, B)
SELECT A, B FROM Kind WHERE A > 1 ORDER BY A, B
index.yaml
when you run using the dev app server.)index.yaml
entriesSELECT A, B FROM Kind
→ Index(Kind, A, B)
SELECT A, B, C FROM Kind
→ Index(Kind, A, B, C)
Suppose we have a model like this, and a standard non-projection query...
from google.appengine.ext import ndb class Greeting(ndb.Model): """Models an individual Guestbook entry.""" content = ndb.StringProperty() date = ndb.DateTimeProperty(auto_now_add=True) author = ndb.UserProperty() uprop = ndb.StringProperty() uprop2 = ndb.StringProperty() ... uprop9 = ndb.StringProperty() @classmethod def query_book(cls, ancestor_key): return cls.query(ancestor=ancestor_key).order(-cls.date) ... greetings = Greeting.query_book(ancestor_key).fetch(50)
The autogenerated index in app.yaml
will look like this:
- kind: Greeting ancestor: yes properties: - name: date direction: desc
But, we don't want to fetch all these properties! A projection query version:
class Greeting(ndb.Model): """Models an individual Guestbook entry.""" content = ndb.StringProperty() date = ndb.DateTimeProperty(auto_now_add=True) author = ndb.UserProperty() uprop = ndb.StringProperty() uprop2 = ndb.StringProperty() ... uprop9 = ndb.StringProperty() @classmethod def query_book(cls, ancestor_key): return cls.query(ancestor=ancestor_key).order(-cls.date) ... greetings = Greeting.query_book(ancestor_key).fetch( 50, projection=[Greeting.content, Greeting.author])
The autogenerated index in app.yaml
for the projection query:
- kind: Greeting ancestor: yes properties: - name: date direction: desc - name: author - name: content
What if we project on date, too?
... greetings = Greeting.query_book(ancestor_key).fetch( 50, projection=[Greeting.content, Greeting.author, Greeting.date])
No change to the index:
- kind: Greeting ancestor: yes properties: - name: date direction: desc - name: author - name: content
PersistenceManager pm = PMF.get().getPersistenceManager(); // ... try { for (int i =0; i < NUM_RETRIES; i++) { pm.currentTransaction().begin(); // ...do the transaction work ... try { pm.currentTransaction().commit(); break; } catch (JDOCanRetryException e1) { if (i == (NUM_RETRIES - 1)) { throw e1; } } } } finally { if (pm.currentTransaction().isActive()) { pm.currentTransaction().rollback(); } pm.close(); }