You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firestore查询:如何获取拥有至少一个Items子集合文档的Project文档

How to Fetch Projects with Non-Empty Items Subcollections in Firestore

Great question! Unfortunately, the query you tried (where("Items.size", ">", 0)) won't work directly because Firestore doesn't automatically track the size of subcollections in parent documents. Subcollections are separate entities, so their count isn't stored as a field in the Project document by default.

But don't worry—there are two reliable ways to achieve what you want:

The most efficient approach is to manually keep a counter of items in each Project document. Every time you add or delete an Item, you update this counter. Then you can query against it easily.

Example Code:

First, when adding an Item to a Project:

// Assuming you have a projectRef pointing to the specific Project document
const projectRef = doc(getDB(), "Projects", "projectId");
const itemRef = doc(collection(projectRef, "Items"));

// Use a transaction to ensure the count is updated correctly
await runTransaction(getDB(), async (transaction) => {
  const projectDoc = await transaction.get(projectRef);
  if (!projectDoc.exists()) {
    throw new Error("Project does not exist!");
  }
  // Increment the itemCount (default to 0 if it doesn't exist)
  const newCount = (projectDoc.data().itemCount || 0) + 1;
  transaction.update(projectRef, { itemCount: newCount });
  // Add the new Item
  transaction.set(itemRef, { /* your item data */ });
});

Then, to query all Projects with at least one Item:

const querySnapshot = await getDocs(
  collection(getDB(), "Projects"),
  where("itemCount", ">", 0)
);

// Process the results
querySnapshot.forEach((doc) => {
  console.log("Project with items:", doc.id, doc.data());
});

This method is fast and scalable because it leverages Firestore's indexed queries. Just make sure to handle deletions too—decrement the itemCount when removing an Item.

2. Use a Collection Group Query (Alternative)

If you don't want to maintain a counter, you can use a collection group query to fetch all Items, then get their parent Project documents. However, you'll need to deduplicate results since multiple Items belong to the same Project.

Example Code:

// Get all Items across all Projects
const itemsQuery = query(collectionGroup(getDB(), "Items"));
const itemsSnapshot = await getDocs(itemsQuery);

// Collect unique Project IDs
const projectIds = new Set();
itemsSnapshot.forEach((itemDoc) => {
  // Get the parent Project document ID from the item's path
  const projectId = itemDoc.ref.parent.parent.id;
  projectIds.add(projectId);
});

// Fetch each unique Project
const projectsWithItems = [];
for (const projectId of projectIds) {
  const projectDoc = await getDoc(doc(getDB(), "Projects", projectId));
  if (projectDoc.exists()) {
    projectsWithItems.push({ id: projectDoc.id, ...projectDoc.data() });
  }
}

console.log("Projects with items:", projectsWithItems);

Note that this approach can be less efficient if you have a large number of Items, as it first fetches all Items before getting the Projects. It's best suited for smaller datasets.


内容的提问来源于stack exchange,提问作者Obiwahn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:53:11