CollectionGroupQuery pero limita la búsqueda a subcolecciones de un documento en particular

Resuelto D V Ramana asked hace 54 años • 0 respuestas

Esta es la estructura de mi base de datos.
ciudades -> puntos de referencia -> atracciones (cada una es una colección)

Consulta
Enumere todas las atracciones de una ciudad en particular.

Solución
Guarde city_id en cada documento de atracción
Utilice una consulta de grupo de colección y un filtro basado en city_id para obtener atracciones de una ciudad en particular.

Mi pregunta
En lugar de guardar city_id en cada documento de atracción, ¿puedo simplemente especificar el documento en collectionGroupQuery que ahora solo busca en subcolecciones bajo este documento en particular?

En el ejemplo anterior, especifico la ruta completa del documento de la ciudad y debería poder enumerar todas las atracciones sin filtrar según city_id.

D V Ramana avatar Jan 01 '70 08:01 D V Ramana
Aceptado

Esto debería funcionar usando FieldPath.documentId().

Cada documento tiene un __name__campo oculto en sus datos y este es el objetivo de FieldPath.documentId().

Para una consulta de colección normal, FieldPath.documentId()sería solo el ID del documento. Sin embargo, para una consulta de grupo de colección, este valor es la ruta del documento.

Deberíamos poder usar esto para encontrar todas las rutas de documentos coincidentes que comiencen con la ruta del documento de la ciudad dada, así:

const cityRef = firebase.firestore().doc('cities/cityId');

firebase.firestore().collectionGroup('attractions')
  .orderBy(firebase.firestore.FieldPath.documentId())
  .startAt(cityRef.path + "/"),
  .endAt(cityRef.path + "/\uf8ff")
  .get()
  .then((querySnapshot) => {
    console.log("Found " + querySnapshot.size + " docs");
    querySnapshot.forEach((doc) => console.log("> " + doc.ref.path))
  })
  .catch((err) => {
    console.error("Failed to execute query", err);
  })

Editar: si bien el código anterior funcionaría si el SDK lo permitiera , actualmente arroja un error sobre tener un número impar de segmentos debido al archivo /.

Por ahora, siempre que todos los ID de su ciudad tengan la misma longitud (como lo serían si usara el valor predeterminado docRef.add()), el siguiente código funcionaría:

const cityRef = firebase.firestore().doc('cities/cityId');

firebase.firestore().collectionGroup('attractions')
  .orderBy(firebase.firestore.FieldPath.documentId())
  .startAt(cityRef.path),
  .endAt(cityRef.path + "\uf8ff")
  .get()
  .then((querySnapshot) => {
    console.log("Found " + querySnapshot.size + " docs");
    querySnapshot.forEach((doc) => console.log("> " + doc.ref.path))
  })
  .catch((err) => {
    console.error("Failed to execute query", err);
  })

Donde falla el bloque anterior es si el ID del documento tiene diferentes longitudes. Digamos que solo desea documentos en "/cities/New York", si otra ciudad llamada "New Yorkshire"también estuviera en la colección de ciudades, también se incluirían sus resultados.

samthecodingman avatar Jun 19 '2021 18:06 samthecodingman