Хранилище данных приложений: как реализовать сообщения и теги без соединений?

Я создаю приложение в Google App Engine (Java), где пользователи могут создавать сообщения, и я подумываю добавить теги к этим сообщениям, поэтому у меня будет что-то вроде этого:

в сообщении объекта:

public List<Key> tags;

в теге субъекта:

public List<Key> posts;

Было бы легко запросить, например, все сообщения с определенным тегом, но как я могу получить все сообщения, содержащие список тегов? Я мог бы сделать запрос для каждого тега, а затем сделать пересечение результатов, но, возможно, есть лучший способ... потому что это будет медленным с большим количеством сообщений.

Еще одна вещь, которая может быть более сложной - это иметь пост, получать сообщения, которые имеют общие теги, упорядоченные по числу общих тегов, поэтому я мог бы каким-то образом получить "похожие" сообщения этому.

Ну, с объединениями это было бы намного проще, но я начинаю с механизма приложения и не могу действительно думать о хорошем способе заменить соединения.

Спасибо!

Ответ 1

В этом дизайне я боюсь, что ваш тег Entity может быть узким местом, особенно если вы ожидаете, что некоторые теги будут очень распространены. Три конкретных вопроса, о которых я могу думать, - это эффективность ваших попыток, пометок, написания раздора и взрывающихся индексов. Давайте посмотрим на stackoverflow для примера - сейчас есть 14 000 сообщений с меткой "java".

  • Это означает, что каждый раз, когда вам нужно получить свой объект java-тега, вы извлекаете ключевые данные из 14 тыс. данных из хранилища данных. то вы отправляете все обратно, когда делаете ставку. которые могут содержать до нескольких байтов.
  • В дополнение к байтам, идущим взад и вперед, каждый столбец требует обновления индексов. каждая запись в ListProperty отображает отдельную запись индекса. так что теперь вы делаете множество обновлений индексов. что приводит нас к числу 3...
  • Взрывающие индексы. каждый объект имеет ограничение на количество записей индекса, которое может иметь. Я думаю, что предел составляет 5000 на сущность. так что на самом деле это трудный предел в отношении того, сколько сообщений может иметь один и тот же тег.

Дальнейшее чтение:

Хорошей новостью является то, что некоторые из ваших требований будут легко обрабатываться только объектом Post. Например, вы можете легко найти все сообщения, у которых есть весь список тегов с фильтром запросов следующим образом:

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

Для всех сообщений с тегами java или appengine вам нужно сделать один запрос для каждого тега, а затем объединить результаты самостоятельно. Хранилище данных не обрабатывает операции типа OR/IN прямо сейчас.

Поиск похожих сообщений звучит сложно. Я подумаю об этом после кофе.

Ответ 2

Возможно, вы захотите проверить это видео из Google IO. Объекты индекса привязки - это то, что вам нужно, и позволяет удалить List<Key> posts в объекте Tag. Также как List<Key> tags для объекта Post.