Firebase Query Double Nested

Dada la estructura de datos a continuación en firebase, quiero ejecutar una consulta para recuperar el blog ‘efg’. No sé la identificación del usuario en este momento.

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

La API de Firebase solo le permite filtrar niños de un nivel de profundidad (o con una ruta conocida ) con sus métodos orderByChild e equalTo .

Entonces, sin modificar / expandir su estructura actual de datos que simplemente deja la opción de recuperar todos los datos y filtrarlos desde el lado del cliente:

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

Por supuesto, esto es altamente ineficiente y no se escalará cuando tenga una cantidad no trivial de usuarios / blogs.

Entonces, la solución común a eso es un llamado índice para su árbol que mapea la clave que está buscando en la ruta donde reside:

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

Luego puede acceder rápidamente al blog usando:

 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(); }); }); 

También es posible que desee reconsiderar si puede reestructurar sus datos para ajustarse mejor a su caso de uso y las limitaciones de Firebase. Tienen una buena documentación sobre la estructuración de sus datos, pero la más importante para las personas nuevas en NoSQL / bases de datos jerárquicas parece ser “evitar la construcción de nidos” .

También vea mi respuesta en la consulta de Firebase si child of child contiene un valor para un buen ejemplo.

Dada su estructura de datos actual, puede recuperar el usuario que contiene la publicación de blog que está buscando.

 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 usar limitToLast ya que los objetos se ordenan al último cuando se usan los documentos de orderByChild .