defprint_author_tags():query=Article.query()articles=query.fetch(20,projection=[Article.author,Article.tags])forarticleinarticles:print(article.author)print(article.tags)# article.title will raise a ndb.UnprojectedPropertyError
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["わかりにくい","hardToUnderstand","thumb-down"],["情報またはサンプルコードが不正確","incorrectInformationOrSampleCode","thumb-down"],["必要な情報 / サンプルがない","missingTheInformationSamplesINeed","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-09-04 UTC。"],[[["\u003cp\u003eThis page outlines the use of projection queries within the legacy bundled services and APIs, which are exclusive to first-generation runtimes in the App Engine standard environment, and notes a migration guide if you are using the second-generation.\u003c/p\u003e\n"],["\u003cp\u003eProjection queries allow for the retrieval of specific properties from Datastore entities, reducing latency and costs compared to retrieving entire entities.\u003c/p\u003e\n"],["\u003cp\u003eYou can filter and sort projection queries like standard entity queries, but they can only be performed on indexed properties, and those used in equality or membership filters are not allowed to be projected.\u003c/p\u003e\n"],["\u003cp\u003eProjection queries with multiple-valued properties will return a separate entity for each combination of projected values, and be mindful that having more than one multiple-valued property can lead to an exploding index.\u003c/p\u003e\n"],["\u003cp\u003eAll properties specified in the projection need to be in a Datastore index, and consistently projecting the same properties can help minimize the number of indexes required.\u003c/p\u003e\n"]]],[],null,["# Projection Queries\n\n| This page describes how to use the legacy bundled services and APIs. This API can only run in first-generation runtimes in the App Engine standard environment. If you are updating to the App Engine Python 3 runtime, refer to the [migration guide](/appengine/migration-center/standard/migrate-to-second-gen/python-differences) to learn about your migration options for legacy bundled services.\n\n\u003cbr /\u003e\n\nMost Datastore [queries](/appengine/docs/legacy/standard/python/datastore/queries) return whole [entities](/appengine/docs/legacy/standard/python/datastore/entities) as their results, but often an application is actually interested in only a few of the entity's properties. *Projection queries* allow you to query Datastore for just those specific properties of an entity that you actually need, at lower latency and cost than retrieving the entire entity.\n\nProjection queries are similar to SQL queries of the form: \n\n SELECT name, email, phone FROM CUSTOMER\n\nYou can use all of the filtering and sorting features available for standard entity queries, subject to the [limitations](#Limitations_on_projections) described below. The query returns abridged results with only the specified properties (`name`, `email`, and `phone` in the example) populated with values; all other properties have no data.\n\nUsing projection queries in Python 2\n------------------------------------\n\nConsider the following model:\n\n\u003cbr /\u003e\n\n class Article(ndb.Model):\n title = ndb.StringProperty()\n author = ndb.StringProperty()\n tags = ndb.StringProperty(repeated=True)\n\nYou specify a projection this way: \n\n def print_author_tags():\n query = Article.query()\n articles = query.fetch(20, projection=[Article.author, Article.tags])\n for article in articles:\n print(article.author)\n print(article.tags)\n # article.title will raise a ndb.UnprojectedPropertyError\n\nYou handle the results of these queries just as you would for a standard entity query: for example, by iterating over the results. \n\n for article in articles:\n print(article.author)\n print(article.tags)\n # article.title will raise a ndb.UnprojectedPropertyError\n\nYou can project indexed sub-properties from a structured property. To get only the `city` property of a contact's `address` structured property, you could use a projection like: \n\n class Address(ndb.Model):\n type = ndb.StringProperty() # E.g., 'home', 'work'\n street = ndb.StringProperty()\n city = ndb.StringProperty()\n\n`...` \n\n class Contact(ndb.Model):\n name = ndb.StringProperty()\n addresses = ndb.StructuredProperty(Address, repeated=True)\n\n`...` \n\n Contact.query().fetch(projection=[\"name\", \"addresses.city\"])\n Contact.query().fetch(projection=[Contact.name, Contact.addresses.city])\n\nGrouping^(experimental)^\n------------------------\n\nProjection queries can use the `distinct` keyword to ensure that only completely unique results will be returned in a result set. This will only return the first result for entities which have the same values for the properties that are being projected. \n\n Article.query(projection=[Article.author], group_by=[Article.author])\n Article.query(projection=[Article.author], distinct=True)\n\nBoth queries are equivalent and will produce each author's name only once.\n\n\nLimitations on projections\n--------------------------\n\nProjection queries are subject to the following limitations:\n\n- **Only indexed properties can be projected.**\n\n Projection is not supported for properties that are not indexed, whether explicitly or implicitly. Long text strings ([`Text`](/appengine/docs/legacy/standard/python/ndb/entity-property-reference#types)) and long byte strings ([`Blob`](/appengine/docs/legacy/standard/python/ndb/entity-property-reference#types)) are not indexed.\n- **The same property cannot be projected more than once.**\n\n- **Properties referenced in an equality (`=`) or membership (`IN`) filter cannot be projected.**\n\n For example, \n\n SELECT A FROM kind WHERE B = 1\n\n is valid (projected property not used in the equality filter), as is \n\n SELECT A FROM kind WHERE A \u003e 1\n\n (not an equality filter), but \n\n SELECT A FROM kind WHERE A = 1\n\n (projected property used in equality filter) is not.\n- **Results returned by a projection query cannot be saved back to Datastore.**\n\n Because the query returns results that are only partially populated, you cannot write them back to Datastore.\n\nProjections and multiple-valued properties\n------------------------------------------\n\nProjecting a property with multiple values will not populate all values for that property. Instead, a separate entity will be returned for each unique combination of projected values matching the query. For example, suppose you have an entity of kind `Foo` with two multiple-valued properties, `A` and `B`: \n\n entity = Foo(A=[1, 1, 2, 3], B=['x', 'y', 'x'])\n\nThen the projection query \n\n SELECT A, B FROM Foo WHERE A \u003c 3\n\nwill return four entities with the following combinations of values:\n\n`A` = `1`, `B` = `'x'` \n\n`A` = `1`, `B` = `'y'` \n\n`A` = `2`, `B` = `'x'` \n\n`A` = `2`, `B` = `'y'`\n\nNote that if an entity has a multiple-valued property with no values, no entries\nwill be included in the index, and no results for that entity will be returned\nfrom a projection query including that property.\n| **Warning:** Including more than one multiple-valued property in a projection will result in an [exploding index](/appengine/docs/legacy/standard/python/datastore/indexes#index-limits).\n\nIndexes for projections\n-----------------------\n\nProjection queries require all properties specified in the projection to be included in a Datastore [index](/appengine/docs/legacy/standard/python/datastore/indexes). The App Engine development server automatically generates the needed indexes for you in the index configuration file, `index.yaml`, which is uploaded with your application.\n\nOne way to minimize the number of indexes required is to project the same properties consistently, even when not all of them are always needed. For example, these queries require two separate indexes: \n\n SELECT A, B FROM Kind\n SELECT A, B, C FROM Kind\n\nHowever, if you always project properties `A`, `B`, and `C`, even when `C` is not required, only one index will be needed.\n\nConverting an existing query into a projection query may require building a new index if the properties in the projection are not already included in another part of the query. For example, suppose you had an existing query like \n\n SELECT * FROM Kind WHERE A \u003e 1 ORDER BY A, B\n\nwhich requires the index \n\n Index(Kind, A, B)\n\nConverting this to either of the projection queries \n\n SELECT C FROM Kind WHERE A \u003e 1 ORDER BY A, B\n SELECT A, B, C FROM Kind WHERE A \u003e 1 ORDER BY A, B\n\nintroduces a new property (`C`) and thus will require building a new index `Index(Kind,` `A,` `B,` `C)`. Note that the projection query \n\n SELECT A, B FROM Kind WHERE A \u003e 1 ORDER BY A, B\n\nwould *not* change the required index, since the projected properties `A` and `B` were already included in the existing query."]]