Esto se copia de mi respuesta en el Objectify-appengine grupo de Google: https://groups.google.com/forum/?fromgroups#!topic/objectify-appengine/LlOyRJZRbnk
Hay tres opciones principales cuando se trata de "datos de agregación", como lo que describes:
1) Cálmelo cuando lo necesite
Ha concluido, con razón, creo, que esto es demasiado caro.
2) Calcular a intervalos lotes y almacenar este resultado
No muy satisfactorio ya que implica un retraso. Además, no desea peinar toda su base de datos todas las noches.
3) Actualización de la agregación cuando los datos cambian
Este enfoque implica un poco más de trabajo cada vez que cambian los datos, pero es casi seguro que lo que quiere hacer.
Crea algún tipo de colección de contactos para cada usuario. Cuando llega un mensaje, asegúrese de que exista un contacto del remitente para ese destinatario. Quizás también quiera eliminar el contacto cuando el destinatario borre el último mensaje de un remitente.
Tenga cuidado de no tropezar con los límites de velocidad de transacción del grupo de entidades (una escritura por segundo).Me voy a caminar a través de algunas opciones:
1) Se puede almacenar una lista de contactos en cada destinatario:
class Person {
@Id Long id;
Set<Key<Person>> contacts;
}
Esto sería un problema distinto si, por ejemplo, el destinatario recibe el correo de 20 nuevos personas a la vez. Esto es casi seguro una mala idea. Por otro lado, es tremendamente rápido y eficiente buscar quiénes son tus contactos. Una pequeña mejora sería mover esto en una entidad separada padre es la persona por lo que no siempre va a cargar esos datos:
class Contacts {
@Parent Key<Person> owner;
@Id long id = 1; // there's only ever one of these per person, and it should have a predictable key for fetching
Set<Key<Person>> contacts;
}
Por supuesto, el conjunto en una sola entidad le da un límite de 50.000 de entrada. Podría ser un poco más pequeño que esto si primero tocas el límite de tamaño de la entidad de 1M. Si sus claves son ~ 20 caracteres, será más o menos lo mismo. Si esto es un problema, puede permitir varias entidades de contactos, en cuyo punto tiene algo parecido al patrón de entidad de índice de relación de la charla de E/S de Google 2009 de Brett Slatkin: http://www.youtube.com/watch?v=AgaL6NGpkB8
2) Puede almacenar una lista de contactos en la otra dirección
class Person {
@Id Long id;
@Index Set<Key<Peson>> contactOf;
}
Esto hace que sea un poco más caro para averiguar quiénes son sus contactos son - que necesita una consulta de solo claves, no una clave Ver por simple. Pero ya no estás realmente limitado por la tasa de escritura de la entidad. La gente probablemente no envíe más de un mensaje por segundo, y si envían 1000 mensajes en bloque, puede actualizar el contacto en una sola transacción.
Como el anterior, es probable que quieren mover este índice en una entidad separada:
class Contacts {
@Parent Key<Person> person;
@Id long id = 1; // there's only ever one of these per person, and it should have a predictable key for fetching
Set<Key<Person>> of;
}
3) También puede almacenar estos contactos en una entidad completamente separada
class Contact {
@Parent Key<Person> person;
@Id Long id;
@Index Key<Person> owner;
}
Esto realmente es sólo una forma menos eficiente de espacio de hacer la solución n. ° 2.
Lo importante es seguir actualizando esta estructura cuando se envía o recibe cada mensaje.
Gracias por su amplia respuesta. Estoy haciendo algunas preguntas de seguimiento en google-appengine-group. – spierce7
Tiene un límite de 5.000, no 50.000, probablemente un error tipográfico. – gswierczynski