Referência de propriedade da entidade

O Firestore no modo Datastore (Datastore) é compatível com vários tipos de dados para valores de propriedade. Estes são alguns deles:

  • Números inteiros
  • Números de ponto flutuante
  • Strings
  • Datas
  • dados binários

Para conseguir uma lista completa de tipos, consulte Propriedades e tipos de valor.

Propriedades e tipos de valor

Os valores de dados associados a uma entidade consistem em uma ou mais propriedades. Cada propriedade tem um nome e um ou mais valores. Uma propriedade pode ter valores de mais de um tipo, e duas entidades podem ter valores de tipos diferentes para a mesma propriedade. As propriedades podem ser indexadas ou não (consultas que ordenam ou filtram com base em uma propriedade P ignoram entidades em que P não seja indexada). Uma entidade pode ter no máximo 20.000 propriedades indexadas.

Estes são os tipos de valor compatíveis:

Tipo de valor Tipo(s) de Java Ordem de classificação Observações
Número inteiro short
int
long
java.lang.Short
java.lang.Integer
java.lang.Long
Numérico Armazenado como número inteiro longo e convertido no tipo de campo

Excesso de valores fora do intervalo
Número de ponto flutuante float
double
java.lang.Float
java.lang.Double
Numérico Precisão dupla de 64 bits,
IEEE 754
Booleanos boolean
java.lang.Boolean
false<true
String de texto (curta) java.lang.String Unicode Até 1.500 bytes

Valores maiores que 1.500 bytes geram IllegalArgumentException
String de texto (longa) com.google.appengine.api.datastore.Text Nenhum Até 1 megabyte

Não indexado
String de bytes (curta) com.google.appengine.api.datastore.ShortBlob Ordem de bytes Até 1.500 bytes

Valores maiores que 1.500 bytes geram IllegalArgumentException
String de bytes (longa) com.google.appengine.api.datastore.Blob Nenhum Até 1 megabyte

Não indexado
Data e hora java.util.Date Cronológica
Ponto geográfico com.google.appengine.api.datastore.GeoPt Por latitude,
e depois longitude
Endereço postal com.google.appengine.api.datastore.PostalAddress Unicode
Número de telefone com.google.appengine.api.datastore.PhoneNumber Unicode
Endereço de e-mail com.google.appengine.api.datastore.Email Unicode
Usuário das Contas do Google com.google.appengine.api.users.User Endereço de e-mail
em ordem Unicode
Identificador de mensagens instantâneas com.google.appengine.api.datastore.IMHandle Unicode
Link com.google.appengine.api.datastore.Link Unicode
Categoria com.google.appengine.api.datastore.Category Unicode
Classificação com.google.appengine.api.datastore.Rating Numérico
Chave do Datastore com.google.appengine.api.datastore.Key
ou o objeto referenciado (como um filho)
Por elementos do caminho
(tipo, identificador,
tipo, identificador...)
Até 1.500 bytes

Valores maiores que 1.500 bytes geram IllegalArgumentException
Chave Blobstore com.google.appengine.api.blobstore.BlobKey Ordem de bytes
Entidade incorporada com.google.appengine.api.datastore.EmbeddedEntity Nenhuma Não indexado
Nulo null Nenhum

Importante: é altamente recomendável evitar o armazenamento de um users.User como um valor de propriedade, porque isso inclui o endereço de e-mail e o ID exclusivo. Se um usuário alterar o endereço de e-mail, e você comparar o antigo user.User armazenado com o novo valor de user.User, eles não serão correspondentes. Em vez disso, utilize o valor do ID do usuário User como o identificador estável e exclusivo do usuário.

Para strings de texto e dados binários não codificados (strings de bytes), o Datastore aceita dois tipos de valor:

  • Strings curtas (até 1500 bytes) são indexadas e podem ser usadas em condições de filtro de consulta e ordens de classificação.
  • Strings longas (até 1 megabyte) não são indexadas e não podem ser usadas em filtros de consulta e ordens de classificação.
Observação: o tipo de string de bytes longa é nomeado como Blob na API Datastore. Esse tipo não está relacionado aos blobs, conforme usado na API Blobstore.

Quando uma consulta envolve um campo com valores de tipos mistos, o Firestore usa uma ordem determinista com base nas representações internas:

  1. Valores nulos
  2. Números de ponto fixo
    • Números inteiros
    • Datas e horas
    • Classificações
  3. Valores booleanos
  4. Sequências de bytes
    • String de bytes
    • String Unicode
    • Chaves do Blobstore
  5. Números de ponto flutuante
  6. Pontos geográficos
  7. Usuários das Contas do Google
  8. Chaves do armazenamento de dados

Como strings de texto longas, strings de bytes longas e entidades incorporadas não são indexadas, elas não têm nenhuma ordem definida.

Propriedades repetidas

É possível armazenar diversos valores dentro de uma única propriedade.

Entity employee = new Entity("Employee");
ArrayList<String> favoriteFruit = new ArrayList<String>();
favoriteFruit.add("Pear");
favoriteFruit.add("Apple");
employee.setProperty("favoriteFruit", favoriteFruit);
datastore.put(employee);

// Sometime later
employee = datastore.get(employee.getKey());
@SuppressWarnings("unchecked") // Cast can't verify generic type.
    ArrayList<String> retrievedFruits = (ArrayList<String>) employee
    .getProperty("favoriteFruit");

Entidades incorporadas

Às vezes, pode ser conveniente incorporar uma entidade como propriedade de outra entidade. Isso pode ser útil, por exemplo, para criar uma estrutura hierárquica de valores de propriedade dentro de uma entidade. A classe Java EmbeddedEntity permite que você realize as ações a seguir:

// Entity employee = ...;
EmbeddedEntity embeddedContactInfo = new EmbeddedEntity();

embeddedContactInfo.setProperty("homeAddress", "123 Fake St, Made, UP 45678");
embeddedContactInfo.setProperty("phoneNumber", "555-555-5555");
embeddedContactInfo.setProperty("emailAddress", "test@example.com");

employee.setProperty("contactInfo", embeddedContactInfo);

As propriedades de uma entidade incorporada não são indexadas e não podem ser usadas em consultas. Também é possível associar uma chave a uma entidade incorporada, mas ao contrário de uma entidade completa, a chave não é necessária e, mesmo presente, não pode ser usada para recuperar a entidade.

Em vez de preencher manualmente as propriedades da entidade incorporada, use o método setPropertiesFrom() para copiá-las de uma entidade atual:

// Entity employee = ...;
// Entity contactInfo = ...;
EmbeddedEntity embeddedContactInfo = new EmbeddedEntity();

embeddedContactInfo.setKey(contactInfo.getKey()); // Optional, used so we can recover original.
embeddedContactInfo.setPropertiesFrom(contactInfo);

employee.setProperty("contactInfo", embeddedContactInfo);

Você pode usar o mesmo método depois para recuperar a entidade original da entidade incorporada:

Entity employee = datastore.get(employeeKey);
EmbeddedEntity embeddedContactInfo = (EmbeddedEntity) employee.getProperty("contactInfo");

Key infoKey = embeddedContactInfo.getKey();
Entity contactInfo = new Entity(infoKey);
contactInfo.setPropertiesFrom(embeddedContactInfo);

Como usar uma lista vazia

Historicamente, o Datastore não tinha uma representação para uma propriedade que representasse uma lista vazia. O SDK do Java contornou isso armazenando coleções vazias como valores nulos. Portanto, não há como fazer a distinção entre valores nulos e listas vazias. Para manter a compatibilidade com versões anteriores, isso continua sendo o comportamento padrão, resumido da seguinte maneira:

  • As propriedades nulas são gravadas como nulas no Datastore.
  • As coleções vazias são gravadas como nulas no Datastore.
  • Um nulo é lido como nulo pelo Datastore.
  • Uma coleção vazia é lida como nula.

No entanto, se você alterar o comportamento padrão, o SDK do Appengine Datastore Java aceitará o armazenamento de listas vazias. Recomendamos que pense nas implicações de alterar o comportamento padrão do aplicativo e ativar o suporte para listas vazias.

Para alterar o comportamento padrão para usar listas vazias, defina a propriedade DATASTORE_EMPTY_LIST_SUPPORT durante a inicialização do app conforme a seguir:

System.setProperty(DatastoreServiceConfig.DATASTORE_EMPTY_LIST_SUPPORT, Boolean.TRUE.toString());

Com esta propriedade definida como true, como mostrado acima:

  • As propriedades nulas são gravadas como nulas no Datastore.
  • As coleções vazias são gravadas como uma lista vazia no Datastore.
  • Um nulo é lido como nulo pelo Datastore.
  • Durante a leitura pelo Datastore, uma lista vazia é retornada como uma Collection vazia.