te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How to get parent document of firestore collectionGroup query? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to get parent document of firestore collectionGroup query? - Stack Overflow

programmeradmin2浏览0评论

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

I got all the documents of position history but I also need some data from position and production. I was hoping if there is a way to get the documents of the parents in a collectionGroup query. I'm also using 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();

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

I got all the documents of position history but I also need some data from position and production. I was hoping if there is a way to get the documents of the parents in a collectionGroup query. I'm also using 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();
Share Improve this question edited Mar 21, 2023 at 14:45 Renaud Tarnec 83.2k10 gold badges97 silver badges129 bronze badges Recognized by Google Cloud Collective asked Dec 30, 2021 at 7:44 MarcShayneMarcShayne 871 silver badge8 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 14

As indicated by Pierre Janineh you need to use the parent properties of the DocumentReference and CollectionReference classes.

Concretely, for each QueryDocumentSnapshot (which "offers the same API surface as a DocumentSnapshot") in the QuerySnapshot you can do:

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 DocumentReferences (and the ids) of the parent and grandparent docs.

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 plicated... because you actually need to query these documents based on their DocumentReferences.

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.

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 DocumentSnapshots from which you can get the data. 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 (i.e. the order in which you loop over the querySnapshot with forEach) but it is a bit cumbersome...

In addition, note that if you have several docs in one of the positionhistory subcollections, you will fecth several time the same parent and grandparent docs. You could maintain a list of the doc IDs that were already fetched but, again, this adds some plexity.

So, for all these reasons, it is probably good to analyse if it's not easier/better to denormalize the data, as explained above.

You can use the QuerySnapshot. It points to a number of QueryDocumentSnapshot instances.

const parent = querySnapshot.ref.parent;

Check out the Firebase Documentation

发布评论

评论列表(0)

  1. 暂无评论