firebase 如何获取firestore collectionGroup查询的父单据?

krugob8w  于 2023-03-24  发布在  其他
关注(0)|答案(2)|浏览(148)

我试图获取所有子集合查询的父文档,这样我的数据库看起来就像这样

/production/id/position/id/positionhistory

我得到了所有的职位历史文件,但我还需要一些数据,从位置和生产。我希望如果有一种方法来获得文件的父母在collectionGroup查询。我也使用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();
gab6jxml

gab6jxml1#

正如Pierre Janineh所指出的,您需要使用DocumentReferenceCollectionReference类的parent属性。
具体来说,对于QuerySnapshot中的每个QueryDocumentSnapshot(“提供与DocumentSnapshot相同的API表面”),您可以执行以下操作:

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
  // ...
});

因此,您可以轻松地获取父文档和祖文档的DocumentReference(和id)。
但是,您希望获取这些父/祖文档的一些数据(“我还需要一些来自位置和生产的数据”),这就比较复杂了...因为您实际上需要根据这些文档的DocumentReference s来查询这些文档。
为此,您可以将Promise.all()与一个或多个在循环中构建的promise数组一起使用(如下所示),但是,根据您需要多少来自父文档的数据,您也可以将数据反规范化,并将来自父文档和祖文档的所需数据添加到子文档中。
要获取所有父文档和祖文档的数据,可以执行以下操作:

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

你将得到两个DocumentSnapshot的数组,你可以从中获取数据。但是你很可能需要将它们中的每一个与其对应的子/孙文档链接起来。
由于使用Promise.all(),返回值将按照传递的Promises的顺序,因此您可以使用初始数组的索引(即使用forEach循环querySnapshot的顺序),但它有点麻烦......
此外,请注意,如果在positionhistory子集合中有多个文档,则会多次获取相同的父文档和祖父文档。您可以维护已获取的文档ID列表,但这又增加了一些复杂性。
因此,出于所有这些原因,如果对数据进行非规范化并不容易/更好,那么分析可能是好的,如上所述。

bvpmtnay

bvpmtnay2#

您可以使用QuerySnapshot。它指向许多QueryDocumentSnapshot示例。

const parent = querySnapshot.ref.parent;

查看Firebase Documentation

相关问题