10

Sto costruendo un'applicazione in Google App Engine (Java), dove gli utenti possono rendere i messaggi e sto pensando ad aggiungere tag a questi posti, così avrò qualcosa di simile:datastore del motore dell'app: come implementare post e tag senza join?

nel soggetto del messaggio:

public List<Key> tags; 

in un'entità tag:

public List<Key> posts; 

sarebbe facile da interrogare, per esempio, tutti i messaggi con un determinato tag, ma come ho potuto ottenere tutti i post che ha una lista di tag? Potrei fare una query per ogni tag e quindi fare un'intersezione dei risultati, ma forse c'è un modo migliore ... perché sarebbe lento con un sacco di post.

Un'altra cosa che può essere più difficile è avere un post, ottenere i posti che hanno in comune i tag ordinati dal numero di tag comuni, così ho potuto ottenere i messaggi "simili" a questo, in qualche modo.

Bene, con i join questo sarebbe molto più semplice, ma sto iniziando con il motore di app e non posso davvero pensare a un buon modo per sostituire i join.

Grazie!

risposta

5

Con questo design, temo che la tua entità tag possa essere un collo di bottiglia, specialmente se ti aspetti che alcuni tag siano molto comuni. Tre problemi specifici a cui posso pensare sono l'efficienza del tuo ottiene e mette, scrive contesa ed esplode indici. Diamo un'occhiata a StackOverflow per un esempio: ci sono 14.000 post taggati "java" in questo momento.

  1. Ciò significa che ogni volta che è necessario recuperare l'entità tag java si stanno ritirando 14k di dati chiave dal datastore. quindi stai rimandando tutto quando fai un put. questo potrebbe sommarsi a molti byte.
  2. Oltre ai byte che vanno avanti e indietro, ogni put richiederà gli indici da aggiornare. ogni voce in ListProperty esegue il mapping su una voce di indice separata. quindi ora stai facendo molti aggiornamenti dell'indice. che ci porta al numero 3 ...
  3. Indexing esplosivi. ogni entità ha un limite sul numero di voci dell'indice che può avere. Penso che il limite sia 5000 per entità. quindi questo è in realtà un duro limite per quanti post potrebbero mai avere lo stesso tag.

Letture consigliate:

La buona notizia è, alcune delle vostre esigenze sarebbe essere facilmente gestito solo dall'entità Post. Per esempio, si potrebbe facilmente trovare tutti i post che hanno tutto di un elenco di tag con un filtro di query come questa:

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

Per tutti i messaggi con sia java o AppEngine tag, si avrebbe bisogno fare una query per ogni tag, quindi combinare i risultati da soli.Il datastore non gestisce le operazioni di tipo OR/IN in questo momento.

Trovare related posts suona complicato. Ci penserò dopo un caffè.

+1

non ho saputo che quando ho recuperato un'entità con una proprietà lista tutte le entità di tale elenco è stato anche recuperato ... E 'in questo modo? Quindi rimuoverò l'elenco Post. Inoltre non ho saputo che avrei potuto interrogare in quel modo su una proprietà lista: q.setFilter ("tag" == 'Java' && "tag == 'appengine'"); Questa è davvero una buona notizia :) Grazie Peter. – Damian

+0

Le entità pieno nelle liste potrebbero o non potrebbero ottenere inverosimile seconda esattamente come implementare le vostre entità e se si sta utilizzando JDO o JPA (leggiamo di prendere gruppi in JDO per esempio) ma anche se solo dovesse caricare le chiavi, alcune migliaia di chiavi inizieranno a sommarsi se le muovi continuamente avanti e indietro. –

1

Si potrebbe voler controllare questo video da Google IO. Le entità dell'indice di relazione sono ciò di cui hai bisogno e ti consente di rimuovere List<Key> posts nell'entità Tag. Così come List<Key> tags sull'entità Post.

Problemi correlati