10

Estoy construyendo una aplicación en Google App Engine (Java), donde los usuarios pueden hacer postes y estoy pensando en añadir etiquetas a estos puestos, así que voy a tener algo como esto:Almacén de datos del motor de aplicaciones: ¿cómo implementar publicaciones y etiquetas sin uniones?

en la entidad de la publicación:

public List<Key> tags; 

en la entidad tag:

public List<Key> posts; 

sería fácil de consultar, por ejemplo, todos los mensajes con una determinada etiqueta, pero ¿cómo podría conseguir todos los mensajes que tiene una lista de etiquetas? Podría hacer una consulta para cada etiqueta y luego hacer una intersección de los resultados, pero tal vez haya una mejor manera ... porque sería lento con muchas publicaciones.

Otra cosa que puede ser más difícil es tener una publicación, obtener las publicaciones que tienen etiquetas en común ordenadas por el número de etiquetas comunes, por lo que podría obtener publicaciones "similares" a esta, de alguna manera.

Bueno, con join esto sería mucho más fácil, pero estoy comenzando con el motor de aplicación y realmente no puedo pensar en una buena manera de reemplazar las uniones.

Gracias!

Respuesta

5

Con este diseño, me temo que su Tag Entity podría ser un cuello de botella, especialmente si espera que algunas etiquetas sean muy comunes. Tres problemas específicos en los que puedo pensar son la eficiencia de los objetos que obtiene y pone, la contención de escritura y los índices de explosión. Veamos Stackoverflow para ver un ejemplo: hay 14,000 publicaciones etiquetadas "java" en este momento.

  1. Eso significa que cada vez que necesite recuperar su entidad de etiqueta java, está retirando 14k de datos clave del almacén de datos. entonces lo estás devolviendo todo cuando lo haces. eso podría sumar muchos bytes.
  2. Además de los bytes que van y vienen, cada publicación requerirá que se actualicen los índices. cada entrada en ListProperty se correlaciona con una entrada de índice separada. así que ahora estás haciendo muchas actualizaciones de índice. que nos lleva al número 3 ...
  3. Exploding Indexes. cada entidad tiene un límite en la cantidad de entradas de índice que puede tener. Creo que el límite es de 5000 por entidad. así que, en realidad, es un límite estricto sobre cuántas publicaciones podrían tener la misma etiqueta.

Lectura adicional:

La buena noticia es que algunos de sus requisitos haría ser manejado fácilmente solo por la entidad Post. Por ejemplo, se puede encontrar fácilmente todos los mensajes que tienen todo de una lista de etiquetas con un filtro de consulta como esta:

Query q = pm.newQuery(Post.class) 
q.setFilter("tags" == 'Java' && "tags == 'appengine'"); 

Para todos los puestos con ya sea java o appengine etiquetas, lo que se necesita hacer una consulta para cada etiqueta, luego combine los resultados usted mismo.El almacén de datos no maneja las operaciones de tipo OR/IN en este momento.

Encontrar publicaciones relacionadas suena complicado. Lo pensaré después de un café.

+1

No sabía que cuando recuperaba una entidad con una propiedad de lista también se recuperaban todas las entidades en esa lista ... ¿Es así? Así que eliminaré la lista de Publicaciones. Tampoco sabía que podía consultar de esa manera sobre una propiedad de lista: q.setFilter ("tags" == 'Java' && "tags == 'appengine'"); Eso es realmente una buena noticia :) Gracias Peter. – Damian

+0

Las entidades completas en las listas pueden o no obtenerse dependiendo de cómo implementes exactamente tus entidades y si estás usando JDO o JPA (lee sobre grupos de búsqueda en JDO, por ejemplo) Pero incluso si solo estabas cargando las claves, unos cuantos miles de teclas comenzarán a sumarse si los mueve constantemente de un lado a otro. –

1

Quizás desee ver este video en Google IO. Las entidades de índice de relación son lo que necesita y le permite eliminar List<Key> posts en la entidad Tag. Además de List<Key> tags en la entidad Post.

Cuestiones relacionadas