2016-01-16 3 views
0

У меня есть firebase узел следующим образом -Firebase извлечения данных с помощью ключа

providers 
    -userid1 
    --userid : userid1 
    --keywords 
    ---key1 : true 
    ---key2 : true 
    ---key3 : true 
    -userid2 
    --userid : userid2 
    --keywords 
    ---key1 : true 
    ---key4 : true 
    ---key5 : true 

Я хочу, чтобы получить все UserIds, которые имеют «key1» в их ключевых слов ребенка.

Я попробовал следующий запрос

var ref = new Firebase(url+"/providers") 
ref.orderByChild("keywords").equalTo("key1").on("value", function(snapshot){ 
console.log(snapshot.numChildren()); 
}) 

Также попробовал -

var ref = new Firebase(url+"/providers") 
ref.orderByKey().equalTo("key1").on("value", function(snapshot){ 
console.log(snapshot.numChildren()); 
}) 

Я не получить никаких результатов. Что мне не хватает в запросе? Как эти два вопроса отличаются друг от друга? Оба запроса не работают.

ответ

0

Ваш ключ key1 является ключом, а equalTo() используется для проверки значений.

Хитрость заключается в том, чтобы запросить записи, где они key1 ключ имеет значение true:

var ref = new Firebase(url+"/providers") 
ref.orderByChild("keywords/key1").equalTo(true).on("value", function(snapshot){ 
    console.log(snapshot.numChildren()); 
}) 

Не забудьте добавить индексы keywords/key1 и т.д., чтобы ваш rules.json:

"providers": { 
    "$uid": { 
    ".indexOn": ["keywords/key1", "keywords/key2", "keywords/key3", "keywords/key4", "keywords/key5"] 
    } 
} 

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

providers 
    userid1 
    userid : userid1 
    keywords 
     key1 : true 
     key2 : true 
     key3 : true 
    userid2 
    userid : userid2 
    keywords 
     key1 : true 
     key4 : true 
     key5 : true 
providers_by_keyword: 
    key1: 
    userid1: true 
    userid2: true 
    key2: 
    userid1: true 
    key3: 
    userid1: true 
    key4: 
    userid2: true 
    key5: 
    userid2: true 

Теперь вы можете выполнять обе операции без запроса:

  1. получить все ключевые слова для user1: ref.child('users/user1/keywords').on(...
  2. получить все пользователи для key1: ref.parent().child('providers_by_keyword/key1').on(...

Этот подход создания вторичных индексов известен как денормализация в базах данных NoSQL. Он описан в Firebase's denormalizing is normal blog post. Я также рекомендую прочитать это article about NoSQL data modeling.

+0

Спасибо, Frank. Отличный ответ, я все еще немного расплывчатый по индексированию. Этот запрос работал для меня ref.orderByChild ("key1"). On ("value", function (s) { console.log (s.val()); }); Да, вы правы, я, вероятно, могу поддерживать инвертированный индекс. – Nikhil

+1

Интересное решение. Но при запуске данных у вас возникнут проблемы. Или иначе, поскольку приложение получает больше пользователей (и запрос становится медленнее). Денормализация - это путь: потратьте некоторое время на чтение статей, которые я связал, и экспериментируйте с тем, что нужно делать на практике. –

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