简体   繁体   English

如何获取firestore collectionGroup查询的父文档?

[英]How to get parent document of firestore collectionGroup query?

I'm trying to get the parent document of all subcollection queries I get so my database looks something like this我正在尝试获取我得到的所有子集合查询的父文档,所以我的数据库看起来像这样

/production/id/position/id/positionhistory /production/id/position/id/positionhistory

I got all the documents of position history but I also need some data from position and production.我得到了 position 历史的所有文件,但我还需要来自 position 和生产的一些数据。 I was hoping if there is a way to get the documents of the parents in a collectionGroup query.我希望是否有办法在 collectionGroup 查询中获取父母的文档。 I'm also using firestore v9.我也在使用firestore v9。

const getHistory = async () => {
  setLoading(true);
  try {
    const userHisRef = query(
      collectionGroup(db, "positionhistory"),
      where("userid", "==", currentUser.uid)
    );
    const querySnapshot = await getDocs(userHisRef);
    let arr = [];
    querySnapshot.forEach((doc) => {
      console.log(doc.id);
      arr.push(doc.id);
    });

    setLoading(false);
  } catch (err) {
    console.log(err);
    setLoading(false);
    
  }
};
getHistory();

As indicated by Pierre Janineh you need to use the parent properties of the DocumentReference and CollectionReference classes.正如 Pierre Janineh 所指出的,您需要使用DocumentReferenceCollectionReference类的parent属性。

Concretely, for each QueryDocumentSnapshot (which "offers the same API surface as a DocumentSnapshot ") in the QuerySnapshot you can do:具体来说,对于 QuerySnapshot 中的每个QueryDocumentSnapshot (“提供与DocumentSnapshot相同的QuerySnapshot表面”),您可以执行以下操作:

const querySnapshot = await getDocs(userHisRef);
let arr = [];
querySnapshot.forEach((doc) => {

  const docRef = doc.ref;   
  const parentCollectionRef = docRef.parent;   // CollectionReference
  const immediateParentDocumentRef = parentCollectionRef.parent; // DocumentReference
  const grandParentDocumentRef = immediateParentDocumentRef.parent.parent; // DocumentReference
  // ...
});

So you can easily get the DocumentReference s (and the id s) of the parent and grandparent docs.因此,您可以轻松获取父文档和祖父文档的DocumentReference (和id )。

However, you want to get some of the data of these parent/grandparent documents ("I also need some data from position and production") and this is more complicated... because you actually need to query these documents based on their DocumentReference s .但是,您想获取这些父/祖父文档的一些数据(“我还需要来自 position 和生产的一些数据”),这更复杂......因为您实际上需要根据它们的DocumentReference查询这些文档.

For that you could use Promise.all() with one or more arrays of promises that you build in the loop (as rapidly shown below) but, depending on how much data from the parents you need, you could also denormalize your data and add to the children the desired data from their parents and grandparents docs.为此,您可以使用Promise.all()和您在循环中构建的一个或多个 arrays 承诺(如下所示),但是,根据您需要多少来自父母的数据,您还可以对数据进行非规范化并添加从他们的父母和祖父母文档中向孩子们提供所需的数据。

To get the data of all the parent and grandparent docs, you can do as follows:要获取所有父母和祖父母文档的数据,您可以执行以下操作:

const querySnapshot = await getDocs(userHisRef);
let arr = [];

const parentsPromises = [];
const grandparentsPromises = [];

querySnapshot.forEach((doc) => {
  const docRef = doc.ref;   
  const parentCollectionRef = docRef.parent;   // CollectionReference
  const immediateParentDocumentRef = parentCollectionRef.parent; // DocumentReference
  const grandParentDocumentRef = immediateParentDocumentRef.parent.parent; // DocumentReference
  
  parentsPromises.push(getDoc(immediateParentDocumentRef));
  grandparentsPromises.push(getDoc(grandParentDocumentRef));
  // ...
});

const arrayOfParentsDocumentSnapshots = await Promise.all(parentsPromises);
const arrayOfGrandparentsDocumentSnapshots = await Promise.all(grandParentDocumentRef);

You will get two arrays of DocumentSnapshot s from which you can get the data.您将获得DocumentSnapshot的两个 arrays ,您可以从中获取数据。 But you most probably need to link each of them with its corresponding child/grandchild doc...但是您很可能需要将它们中的每一个与相应的子/孙文档链接起来......

Since, with Promise.all() , the returned values will be in order of the Promises passed, you can use the index of the initial array (ie the order in which you loop over the querySnapshot with forEach ) but it is a bit cumbersome... This is why it is probably good to analyse if it's not easier/better to denormalize the data, as explained above.由于使用Promise.all() ,返回的值将按照 Promises 传递的顺序排列,因此您可以使用初始数组的索引(即使用forEach querySnapshot的顺序),但这有点麻烦...这就是为什么分析数据的非规范化是否更容易/更好的原因,如上所述。

You can use the QuerySnapshot .您可以使用QuerySnapshot It points to a number of QueryDocumentSnapshot instances.它指向许多QueryDocumentSnapshot实例。

const parent = querySnapshot.ref.parent;

Check out the Firebase Documentation查看Firebase 文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM