Firebase Query Double Nested

Учитывая структуру данных ниже в firebase, я хочу запустить запрос для извлечения блога efg. На данный момент я не знаю идентификатора пользователя.

{Users :
     "1234567": {
          name: 'Bob',
          blogs: {
               'abc':{..},
               'zyx':{..}
          }
     },
     "7654321": {
          name: 'Frank',
          blogs: {
               'efg':{..},
               'hij':{..}
          }
     }
}

Ответы

Ответ 1

Firebase API позволяет фильтровать дочерние элементы только на один уровень глубины (или с известным путем) с помощью методов orderByChild и equalTo.

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

var ref = firebase.database().ref('Users');
ref.once('value', function(snapshot) {
    snapshot.forEach(function(userSnapshot) {
        var blogs = userSnapshot.val().blogs;
        var daBlog = blogs['efg'];
    });
});

Это, конечно, крайне неэффективно и не будет масштабироваться, если у вас нетривиальное количество пользователей/блогов.

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

{Blogs:
     "abc": "1234567",
     "zyx": "1234567",
     "efg": "7654321",
     "hij": "7654321"
}

Затем вы можете быстро получить доступ к блогу, используя:

var ref = firebase.database().ref();
ref.child('Blogs/efg').once('value', function(snapshot) {
    var user = snapshot.val();
    ref.child('Blogs/'+user+'/blogs').on('value, function(blogSnapshot) {
        var daBlog = blogSnapshot.val();
    });
});

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

Также см. мой ответ на запрос Firebase, если child of child содержит значение для хорошего примера. Я также рекомендовал бы прочитать о отношениях "многие ко многим" в Firebase и этой статье об общем моделировании данных NoSQL.

Ответ 2

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

const db = firebase.database()
const usersRef = db.ref('users')
const query = usersRef.orderByChild('blogs/efg').limitToLast(1)
query.once('value').then((ss) => {
  console.log(ss.val()) //=> { '7654321': { blogs: {...}}}
})

Вам необходимо использовать limitToLast, поскольку объекты сортируются в последнюю очередь при использовании orderByChild документов.

Ответ 3

Это на самом деле очень просто - просто используйте foreslash:

db.ref('Users').child("userid/name")
db.ref('Users').child("userid/blogs")
db.ref('Users').child("userid/blogs/abc")

Не нужно петель или чего-то еще.