Фильтрация и сортировка музыкальной информации в Google App Engine - PullRequest
1 голос
/ 31 июля 2009

Мне нравилось создавать пару простых приложений для GAE, но теперь я озадачен тем, как спроектировать органайзер коллекции музыки на движке приложений. Короче говоря, я не могу понять, как фильтровать несколько свойств при сортировке по другому.

Давайте предположим, что основной моделью является альбом, содержащий несколько свойств, в том числе:

  • Название
  • Исполнитель
  • Метка * * 1 010
  • Год публикации
  • Жанр
  • Длина
  • Список названий треков
  • Список настроений
  • Дата и время вставки в базу данных

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

  • Год публикации
  • Длина альбома
  • Имя исполнителя
  • Когда информация была добавлена ​​в базу данных

Я не знаю, как это сделать, не сталкиваясь с загадкой взрыва индекса. В частности, я бы хотел сделать что-то вроде:

Albums.all().filter('publication_year <', 1980).order('artist_name')

Я знаю, что это невозможно, но какой обходной путь?

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

Есть ли лучший пример модели данных, который я пропускаю? Любой совет?

Ответы [ 3 ]

1 голос
/ 01 августа 2009

Здесь есть несколько вариантов: вы можете фильтровать как можно лучше, а затем сортировать результаты в памяти, как предлагает Алекс, или вы можете переделать свои структуры данных для фильтров равенства вместо фильтров неравенства.

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

1 голос
/ 03 августа 2009

Поскольку хранилище дешево, вы можете создать свои собственные индексные файлы на основе ListProperty с именами ключей, которые отражают критерии сортировки.

class album_pubyear_List(db.Model):
    words = db.StringListProperty()

class album_length_List(db.Model):
    words = db.StringListProperty()

class album_artist_List(db.Model):
    words = db.StringListProperty()

class Album(db.Model):
    blah...

    def save(self):
        super(Album, self).save()

        # you could do this at save time or batch it and do
        # it with a cronjob or taskqueue

        words = []

        for field in ["title", "artist", "label", "genre", ...]:
            words.append("%s:%s" %(field, getattr(self, field)))

        word_records = []
        now = repr(time.time())
        word_records.append(album_pubyear_List(parent=self, key_name="%s_%s" %(self.pubyear, now)), words=words)
        word_records.append(album_length_List(parent=self, key_name="%s_%s" %(self.album_length, now)), words=words)
        word_records.append(album_artist_List(parent=self, key_name="%s_%s" %(self.artist_name, now)), words=words)
        db.put(word_records)

Теперь, когда пришло время поиска, вы создаете соответствующее предложение WHERE и вызываете соответствующую модель

where = "WHERE words = " + "%s:%s" %(field-a, value-a) + " AND " + "%s:%s" %(field-b, value-b) etc.
aModel = "album_pubyear_List" # or anyone of the other key_name sorted wordlist models

indexes = db.GqlQuery("""SELECT __key__ from %s %s""" %(aModel, where))
keys = [k.parent() for k in indexes[offset:numresults+1]] # +1 for pagination
object_list = db.get(keys) # returns a sorted by key_name list of Albums
0 голосов
/ 31 июля 2009

Как вы говорите, вы не можете иметь условие неравенства для одного поля и порядок для другого (или неравенства для двух полей и т. Д., И т. Д.). Обходной путь - просто использовать «лучшее» условие неравенства, чтобы получить данные в памяти (где «лучший» означает то, которое, как ожидается, даст наименьшее количество данных), а затем дополнительно уточнить его и упорядочить по коду Python в вашем приложении.

Понимание списка Python (и другие формы циклов и т. Д.), Метод sort списка и встроенная функция sorted, модуль itertools в стандартной библиотеке и т. Д. - все это очень помогает в создании эти виды задач довольно просто выполнить в самом Python.

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