Consultas de projeção

Na maioria das consultas do Cloud Datastore, entidades inteiras são retornadas como resultados, mas, normalmente, apenas algumas propriedades delas são relevantes para o aplicativo. As consultas de projeção permitem consultar o Cloud Datastore somente para aquelas propriedades específicas de uma entidade da qual você realmente precisa, a uma latência e a um custo menores do que se a recuperasse inteira.

As consultas de projeção são semelhantes às do SQL do formulário:

SELECT name, email, phone FROM CUSTOMER

É possível usar todos os recursos de filtragem e classificação disponíveis para consultas de entidade padrão, sujeitos às limitações descritas abaixo. A consulta retorna um resumo dos resultados, apenas com as propriedades especificadas, name, email e phone no exemplo, preenchidas com valores. As demais propriedades não têm dados.

Como usar consultas de projeção em Python 2

Considere o seguinte modelo:

class Article(ndb.Model):
    title = ndb.StringProperty()
    author = ndb.StringProperty()
    tags = ndb.StringProperty(repeated=True)

Especifique uma projeção desta forma:

def print_author_tags():
    query = Article.query()
    articles = query.fetch(20, projection=[Article.author, Article.tags])
    for article in articles:
        print(article.author)
        print(article.tags)
        # article.title will raise a ndb.UnprojectedPropertyError

A forma de tratar os resultados dessas consultas é a mesma para a consulta de entidade padrão. Por exemplo, iterando os resultados.

for article in articles:
        print(article.author)
        print(article.tags)
        # article.title will raise a ndb.UnprojectedPropertyError

É possível projetar sub-propriedades indexadas a partir de uma propriedade estruturada. Para receber apenas a propriedade city de uma propriedade estruturada address de um contato, use uma projeção como esta:

class Address(ndb.Model):
    type = ndb.StringProperty()  # E.g., 'home', 'work'
    street = ndb.StringProperty()
    city = ndb.StringProperty()
...
class Contact(ndb.Model):
    name = ndb.StringProperty()
    addresses = ndb.StructuredProperty(Address, repeated=True)
...
Contact.query().fetch(projection=["name", "addresses.city"])
Contact.query().fetch(projection=[Contact.name, Contact.addresses.city])

Agrupamento(experimental)

As consultas de projeção usam a palavra-chave distinct para garantir que apenas resultados totalmente exclusivos sejam retornados em um conjunto de resultados. Isso retornará apenas o primeiro resultado de entidades com os mesmos valores das propriedades projetadas.

Article.query(projection=[Article.author], group_by=[Article.author])
Article.query(projection=[Article.author], distinct=True)

Ambas as consultas são equivalentes e produzirão o nome de cada autor apenas uma vez.

Limitações nas projeções

As consultas de projeção estão sujeitas às seguintes limitações:

  • Somente propriedades indexadas podem ser projetadas.

    A projeção não é compatível com propriedades não indexadas, seja de maneira explícita ou implícita. Strings de texto (Text) e de bytes (Blob) longas não são indexadas.

  • A mesma propriedade não pode ser projetada mais de uma vez.

  • Propriedades referenciadas em um filtro de igualdade (=) ou de associação (IN) não são projetadas.

    Por exemplo:

    SELECT A FROM kind WHERE B = 1
    

    é uma consulta válida (a propriedade projetada não é usada no filtro de igualdade), assim como a consulta

    SELECT A FROM kind WHERE A > 1
    

    (não é um filtro de igualdade), mas

    SELECT A FROM kind WHERE A = 1
    

    (propriedade projetada usada no filtro de igualdade) não é.

  • Os resultados retornados por uma consulta de projeção não são salvos no Cloud Datastore.

    Como a consulta retorna resultados parcialmente preenchidos, não é possível gravá-los de volta no Cloud Datastore.

Projeções e propriedades com vários valores

A projeção de uma propriedade com vários valores não preencherá todos os valores dessa propriedade. Em vez disso, uma entidade separada será retornada para cada combinação exclusiva de valores projetados correspondentes à consulta. Por exemplo, suponhamos que você tenha uma entidade do tipo Foo com duas propriedades de vários valores, A e B:

entity = Foo(A=[1, 1, 2, 3], B=['x', 'y', 'x'])

Neste caso, a consulta de projeção

SELECT A, B FROM Foo WHERE A < 3

retornará quatro entidades com as seguintes combinações de valores:

A = 1, B = 'x'
A = 1, B = 'y'
A = 2, B = 'x'
A = 2, B = 'y'

Observe que, se uma entidade tiver uma propriedade de vários valores sem valores, nenhuma entrada será incluída no índice, e nenhum resultado para essa entidade será retornado de uma consulta de projeção, incluindo essa propriedade.

Índices de projeções

As consultas de projeção requerem a inclusão de todas as propriedades especificadas na projeção em um índice do Cloud Datastore. O servidor de desenvolvimento do App Engine gera automaticamente os índices necessários no arquivo de configuração do índice, index.yaml, enviado com o aplicativo.

Uma forma de reduzir o número de índices necessários é projetar as mesmas propriedades consistentemente, mesmo quando nem todas são necessárias. Por exemplo, essas consultas exigem dois índices separados:

SELECT A, B FROM Kind
SELECT A, B, C FROM Kind

No entanto, se você projetar sempre as propriedades A, B e C, mesmo se C não for obrigatória, apenas um índice será necessário.

A conversão de uma consulta em uma projeção talvez exija a criação de um novo índice caso as propriedades dessa projeção não estejam em outra parte da consulta. Por exemplo, suponhamos que você tenha uma consulta como:

SELECT * FROM Kind WHERE A > 1 ORDER BY A, B

que exija o índice

Index(Kind, A, B)

Convertendo-a em uma das consultas de projeção

SELECT C FROM Kind WHERE A > 1 ORDER BY A, B
SELECT A, B, C FROM Kind WHERE A > 1 ORDER BY A, B

apresenta uma nova propriedade (C) e, portanto, exigirá a criação de um novo índice Index(Kind, A, B, C). A consulta de projeção

SELECT A, B FROM Kind WHERE A > 1 ORDER BY A, B

não altera o índice obrigatório, uma vez que as propriedades projetadas A e B já foram incluídas na consulta atual.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Ambiente padrão do App Engine para Python 2