Выберите один из многих методов в базе данных App Engine. - PullRequest
4 голосов
/ 04 августа 2011

В моем приложении App Engine будут «статьи» и «теги».

И есть два метода для реализации этого (благодаря статье Ника Джонсона ):

# one entity just refers others
class Article(db.Model):
  tags = db.ListProperty(Tag)

# via separate "join" table
class ArticlesAndTags(db.Model):
  article = db.ReferenceProperty(Article)
  tag = db.ReferenceProperty(Tag)

Какой из них мне следует выбрать в соответствии со следующими задачами?

  • Создать облако тегов (часто),
  • Выбор статей по тегу (довольно редко)

Ответы [ 4 ]

2 голосов
/ 05 августа 2011

Я создал огромное облако тегов * на GAEcupboard , выбрав первое решение:

class Post(db.Model):
   title = db.StringProperty(required = True)
   tags = db.ListProperty(str, required = True)

Класс тегов имеет свойство counter, которое обновляется каждый раз, когда создается / обновляется / удаляется новое сообщение.

class Tag(db.Model):
    name = db.StringProperty(required = True)
    counter = db.IntegerProperty(required = True)
    last_modified = db.DateTimeProperty(required = True, auto_now = True)

Имея теги, организованные в ListProperty, довольно легко предложить функцию детализации, которая позволяет пользователю составлять различные теги для поиска нужных статей:

Пример: http://www.gaecupboard.com/tag/python/web-frameworks

Поиск осуществляется с помощью:

posts =  Post.all()
posts.filter('tags', 'python').filter('tags', 'web-frameworks')
posts.fetch()

, который вообще не нуждается ни в каком пользовательском индексе.

хорошо, это слишком много, я знаю :)

2 голосов
/ 04 августа 2011

Из-за отсутствия функции «уменьшить» в карте «appengine» «уменьшить» (или группы SQL по типу запроса) облака тегов сложно реализовать эффективно, потому что вам необходимо подсчитать все теги, которые у вас есть, вручную.В какой бы реализации вы ни работали, я бы предложил отдельную модель TagCounter, которая отслеживает, сколько у вас есть тегов.В противном случае запрос тегов может стоить дорого, если их у вас много.

class TagCounter:
   tag = db.ReferenceProperty(Tag)
   counter = db.IntegerProperty(default=0)

Каждый раз, когда вы решаете обновить свои теги для статьи, убедитесь, что вы увеличиваете или уменьшаете эту таблицу соответственно.

Что касается выбора статей по тегу, первой реализации достаточно (вторая - слишком сложная imo).

class Article(db.Model):
  tags = db.ListProperty(Tag)

  @staticmethod
  def select_by_tag(tag):
    return Article.all().filter("tags", tag).run()
1 голос
/ 04 августа 2011

Создание облака тегов в app-engine действительно сложно, потому что хранилище данных не поддерживает конструкцию GROUP BY, обычно используемую для выражения этого;Он также не предоставляет способ упорядочения по длине свойства списка.

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

Это предполагает, что облака тегов следует создавать периодически, кэшировать и отображать так же, как статический контент.Вы должны подумать об этом в API очереди задач.

Другой запрос, перечисляющий статьи по тегам, будет полностью не поддерживаться первой технической техникой, которую вы показали;Инвертируя его, наличие модели тегов со статьями ListProperty поддерживает запрос, но будет страдать из-за конфликта обновлений, когда к нему будут добавляться популярные теги с высокой скоростью.Другой метод, использующий модель ассоциации, не страдает ни от одной из этих проблем, но усложняет задачу удобного выполнения запросов к списку статей.

То, как я справлюсь с этим, - начать с модели ArticlesAndTags, нодобавить некоторые дополнительные данные в модель, чтобы иметь полезный порядок;дата статьи, название статьи - все, что имеет смысл для конкретного типа сайта, который вы делаете.Вам также понадобится монотонная последовательность (скажем, метка времени), чтобы вы знали когда применен тег.

Запрос облака тегов будет поддерживаться с использованием объекта Tag, имеющего Onlyчисловой счетчик статей, а также ссылка на ту же временную метку, которая используется в модели ArticlesAndTags.

Затем очередь задач может запросить 1000 самых старых статей и тегов, которые на новее , чем самый старый тег, суммировать частоты каждого и добавить его к количеству в тегах.Удаление тегов, вероятно, достаточно редко, чтобы они могли немедленно обновить модель тега без особых разногласий, но если это предположение окажется неверным, то события delete должны быть добавлены также к ArticlesAndTags.

0 голосов
/ 04 августа 2011

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

Мне в голову приходят следующие вещи:

- Метод ListProperty делает модели данных более естественными.

- Метод AtriclesAndTags будет означать, что вам придется запрашивать отношения и затем Articles ( тьфу .. ) вместо выполненияArticle.all().filter('tags =', tag).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...