2014-06-24 4 views
9

Я исхожу из фона SQL, поэтому у меня возникла проблема с проектированием моей схемы firebase nosql. Я привык к тому, что могу запросить что-либо, используя предложение WHERE, и это кажется труднее сделать в firebase (хотя производительность EASILY компенсирует это!).Застрял при разработке схемы для базы данных моей базы firebase

Я храню объекты «дорожки» для песен. Эти объекты имеют пары ключ/значение, таких как ARTIST_NAME, название трека, жанр, рейтинг, CREATED_DATE и т.д., как показано ниже:

tracks 
|_____-JPl1zwOzjqoM8xDTFll 
      |____ artist: "Bob" 
      |____ title: "so long" 
      |____ genre: "pop" 
      |____ rating: 52 
      |____ created: 1403129692781 
| 
|_____ -JPv7KnVi8ASQJjRDpvh 
      |____ artist: "Mary" 
      |____ title: "im alright now" 
      |____ genre: "rock" 
      |____ rating: 70 
      |____ created: 1403129692787 

поведение по умолчанию на моем сайте будет перечислять все эти треки, с новейшим добавил в верхней части списка. Я могу установить мой приоритет $, который должен быть создан, и просто превратить его отрицательным (созданным * -1), чтобы добиться этого эффекта, я полагаю.

Но в будущем, я хотел бы иметь возможность фильтровать/запросить список с помощью других средств, например:

  • Извлечь все треки, которые имеют жанр рок, поп, хип-хоп или ,

  • Получить все треки, имеющие рейтинг 80 или более, и были добавлены за последние 7 дней.

Как можно достичь этого в firebase? Я понимаю, что на самом деле есть только два способа упорядочивания данных:

  1. Через значение «ID», который имеет физическое местоположение «firebaseURL.firebaseio.com/tracks/id», который в моем случае , был автоматически выбран для меня, когда я добавляю трек. Это нормально (я думаю), поскольку у меня есть страницы для отдельных страниц треков, в которых перечислены подробности, а URL-адрес моего сайта - это что-то вроде «www.mysite.com/tracks/-JPl1zwOzjqoM8xDTFll».

  2. Используя $ priority, который в моем случае я использовал для «созданного» значения, чтобы упорядочить список в правильном порядке даты.

Учитывая то у меня есть все настроить (и, пожалуйста, дайте мне знать, если есть лучший способ), есть способ, которым я могу легко запросить для определенных жанров или конкретных оценок?

Я прочитал блог «Денормализация ваших данных - это нормально» (https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html), и я думаю, что понимаю. Из того, что описывает Anant, один из способов добиться того, что я хочу, будет, возможно, будет создавать новый объект в firebase для жанра и перечислить все треки там, например, так:

tracks 
|______ All 
     |_____ -JPlB34tJfAJT0rFT0qI 
     |_____ -JPlB32222222222T0qI 
     |_____ -JPlB34wefwefFT0qI 

|______ Rock 
     |_____ -JPlB32222222222T0qI 
     |_____ -JPlB34tJfAJT0rFT0qI 

|______ Pop 
     |_____ -JPlB34wefwefFT0qI 

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

Это имеет смысл, и я бы не прочь этот метод. Но это будет работать только в том случае, если пользователь хочет выбрать все треки только из одного жанра. Что, если они хотят получить все треки от BOTH rock AND pop? Должен ли я хранить другой объект под названием Rock & Поп и хранить трек там каждый раз, когда кто-то подает песню любого жанра?

genre 
|_______pop-rock 
     |_________ -JPlB34tJfAJT0rFT0qI (a rock song) 
     |_________ -JPlB34wefwefFT0qI (a pop song) 
     |_________ -JPlB32222222222T0qI (a rock song) 

Кроме того, было бы больше смысла, чтобы сохранить весь объект дорожки или просто ссылку, используя TrackID?Например, под/жанр/поп:

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

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

Спасибо за любую помощь в этом, это очень оценили. И, пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

ответ

5

В течение следующего года Firebase запускает множество дополнений к API запросов. Контекстный поиск (где foo как bar), вероятно, никогда не будет большим хитом данных в реальном времени - он медленный и громоздкий.

В блоге Firebase есть две статьи блога по SQL-запросам и эквивалентным шаблонам. Я бы порекомендовал вам give it a read-through. В части 2, в частности, говорится о Flashlight.

Почему ElasticSearch и сервис? Подобно хранению и синхронизации данных в режиме реального времени, поиск представляет собой сложную тему с множеством сложностей и возможностью обнаружения. Легко написать предложение where в SQL, и это поможет вам, но оно быстро отстает от ожиданий пользователей.

ES может быть интегрирован с Firebase в оснастке (услуга Flashlight заняла менее 5 минут, чтобы интегрироваться с приложением, в прошлый раз, когда я ее пыталась) и обеспечивает надежные и тщательные возможности поиска.

Итак, до тех пор, пока Firebase не выкатит некоторые функции, изменяющие игру вокруг запросов, я бы предложил checking out this approach в начале, вместо того, чтобы пытаться использовать возможности поиска другими способами.

0

В приведенных выше примерах вы создаете разные иерархии и храните немного данных, но просто вводите идентификаторы в виде ключей. Поэтому, когда вы получите это на клиенте, вы, вероятно, все равно закончите сортировку по некоторым полям данных.

Мне нравится, чтобы Firebase обрабатывал сортировку для меня с помощью многочастных клавиш.

Например, если мне нужно было получить доступ к трекам по жанру и имени исполнителя, я бы создал плоский индексный узел, называемый trackByGenreAndArtist, с ключом, состоящим из genre_name + artist_name + track_name + track_id. Значение будет объектом с именем исполнителя, идентификатором исполнителя, именем дорожки и идентификатором дорожки. Добавление идентификатора просто для обеспечения его уникальности.

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

Предположим, пользователь выбрал жанр «Rock», и она набирает «B» в поле поиска. Вы можете заполнить предсказания ниспадающего меню, захватывая первые десять треков художников, чье имя начинается с «B»:

indexRef.orderByKey().startAt('Rock'+'B').limitToFirst(10); 

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

Если пользователь выбирает предсказание, используйте идентификатор дорожки для извлечения полного объекта дорожки из узла дорожек и идентификатора исполнителя, чтобы получить полный объект художника от узла художников.

Если пользователь другая буква, а затем просто выбросить ваши прогнозы и делать другое предсказание выборкой, например,

indexRef.orderByKey().startAt('Rock'+'Br').limitToFirst(10);

Кроме того, на ваш вопрос о том, что делать, если вам необходимо искать как Rock и поп-жанры? Ну, вы можете сделать два запроса, как те выше довольно быстро

indexRef.orderByKey().startAt('Rock'+'Br').limitToFirst(10);

indexRef.orderByKey().startAt('Pop'+'Br').limitToFirst(10);

Вы могли бы сгруппировать их по отдельности в своем прогностическом выпадающем меню: Первые десять из Rock, а затем в первой десятке из поп-музыки , Если это недостаточно для вас, вы всегда можете сделать много комбинаторных индексов с такими же крошечными объектами данных и каждой уникальной комбинацией жанра, которую можно выбрать как фильтр поиска, я полагаю. Тем не менее, этот «диск дешев, но пользовательское время не является» - это ваша руководящая роль здесь.

Смежные вопросы