tutorial standard ndb how google engine create app python google-app-engine join google-cloud-datastore

python - standard - GAE-¿Cómo vivir sin combinaciones?



ndb google app engine (4)

"Cargar usuario, recorre la lista de amigos y carga sus últimas publicaciones de blog".

Eso es todo lo que es una unión: bucles anidados. Algunos tipos de uniones son bucles con búsquedas. La mayoría de las búsquedas son solo bucles; algunos son hashes.

"Finalmente fusionar todas las publicaciones de blog para encontrar las últimas 10 entradas de blog"

Eso es una ORDEN POR UN LÍMITE. Eso es lo que la base de datos está haciendo por ti.

No estoy seguro de qué es escalable sobre esto; es lo que hace una base de datos de todos modos.

Problema de ejemplo:

Entidades:

  • El usuario contiene un nombre y una lista de amigos (referencias de usuario)
  • La publicación del blog contiene título, contenido, fecha y escritor (usuario)

Requisito:

Quiero una página que muestre el título y un enlace al blog de las últimas 10 publicaciones de un amigo del usuario. También me gustaría la capacidad de mantener la paginación a través de entradas más antiguas.

Solución SQL:

Entonces en tierra sql sería algo así como:

select * from blog_post where user_id in (select friend_id from user_friend where user_id = :userId) order by date

Las soluciones de GAE que puedo pensar son:

  • Cargue al usuario, recorra la lista de amigos y cargue sus últimas publicaciones en el blog. Finalmente, combine todas las publicaciones de blog para encontrar las últimas 10 entradas de blog
  • En una publicación de blog, tenga una lista de todos los usuarios que tienen al escritor como amigo. Esto significaría una simple lectura, pero daría lugar a una sobrecarga de cuota al agregar un amigo que tiene muchas publicaciones en el blog.

No creo que ninguna de estas soluciones se escale.

Estoy seguro de que otros han solucionado este problema, pero he buscado, he visto videos de google io, he leído el código de otros ... ¿Qué me estoy perdiendo?


Si observa cómo se ejecutará la solución SQL que proporcionó, básicamente será así:

  1. Obtener una lista de amigos para el usuario actual
  2. Para cada usuario de la lista, inicie un análisis de índice en publicaciones recientes
  3. Fusionar: une todos los escaneos desde el paso 2, deteniéndose cuando hayas recuperado suficientes entradas

Puede realizar exactamente el mismo procedimiento usted mismo en App Engine, utilizando las instancias de consulta como iteradores y haciendo una fusión unirse sobre ellos.

Tiene razón en que esto no se adaptará bien a un gran número de amigos, pero sufre exactamente los mismos problemas que tiene la implementación de SQL, simplemente no los oculta también: Obtener las últimas 20 entradas (por ejemplo) cuesta aproximadamente O (n log n) trabajo, donde n es la cantidad de amigos.



Aquí hay un ejemplo en python que brilla en http://pubsub-test.appspot.com/ :

Alguien tiene uno para java? Gracias.

from google.appengine.ext import webapp from google.appengine.ext import db class Message(db.Model): body = db.TextProperty(required=True) sender = db.StringProperty(required=True) receiver_id = db.ListProperty(int) class SlimMessage(db.Model): body = db.TextProperty(required=True) sender = db.StringProperty(required=True) class MessageIndex(db.Model): receiver_id = db.ListProperty(int) class MainHandler(webapp.RequestHandler): def get(self): receiver_id = int(self.request.get(''receiver_id'', ''1'')) key_only = self.request.get(''key_only'').lower() == ''on'' if receiver_id: if key_only: keys = db.GqlQuery( ''SELECT __key__ FROM MessageIndex WHERE receiver_id = :1'', receiver_id).fetch(10) messages.extend(db.get([k.parent() for k in keys])) else: messages.extend(Message.gql(''WHERE receiver_id = :1'', receiver_id).fetch(10))