【问题标题】:How to join data from two collections by reference field in Firestore?如何通过 Firestore 中的引用字段连接来自两个集合的数据?
【发布时间】:2021-05-01 18:13:55
【问题描述】:

我的 Firestore 中有 2 个收藏品。一个叫业主,第二个叫独角兽。 所有者只有一个名称字段,而独角兽具有名称和对所有者的引用。 我想要一个查询返回一个看起来像这样的对象数组

unicorns = { id: 123,
                name: Dreamy,
                owner: { id: 1
                         name: John Cane
                       }
               }

我的查询看起来像这样,但缺少一些我无法弄清楚的东西

let unis = [];
      db
      .collection("unicorns")
      .get()
      .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
          let uni = {
            id: doc.id,
            name: doc.data().name,
            owner: doc.data().owner,
          };
          if (uni.owner) {
            doc
              .data()
              .owner.get()
              .then((res) => {
                uni.owner = {
                  id: res.id,
                  name: res.data().name,
                };
                unis.push(uni);
                
              })
              .then(() => {
                setUnicorns(unis);
              })
              .catch((err) => console.error(err));
          } else {
            unis.push(uni);
          }
        });
      })

当我设置独角兽钩子并尝试映射结果时,我没有得到我需要的所有数据

【问题讨论】:

  • 您好@Reem,如果我的回答解决了您的问题,那么您可以通过单击对勾图标接受它,以便其他人知道问题已解决,否则请随时提出更多问题。

标签: firebase react-native google-cloud-firestore react-hooks


【解决方案1】:

您不能对字符串运行.get() 方法。您必须向 Firestore 发出单独的请求以获取所有者文档。我建议在 async 函数中使用 for-of,如下所示。

const db = admin.firestore()

//Declare the reference for collections before the loop starts
const ownersCollection = db.collection("owners")
const unicornsCollection = db.collection("unicorns")

const ownersData = {}

let unis = [];
unicornsCollection.get().then(async (querySnapshot) => {
    for (const doc of querySnapshot) {
        let uni = {
            id: doc.id,
            name: doc.data().name,
            //Assuming the owner field is the UID of owner
            owner: doc.data().owner,
        };
        if (uni.owner) {
            //Check if owner's data is already fetched to save extra requests to Firestore
            if (ownersData[uni.owner]) {
                uni.owner = {
                    id: ownersData[uni.owner].id,
                    name: ownersData[uni.owner].name,
                };
                unis.push(uni);
            } else {
                //User the ownersCollection Reference to get owner information
                ownersCollection.doc(uni.owner).get().then((ownerDoc) => {
                    uni.owner = {
                        id: ownerDoc.data().id,
                        name: ownerDoc.data().name,
                    };
                    ownersData[uni.owner] = {
                        id: ownerDoc.data().id,
                        name: ownerDoc.data().name,
                    }
                    unis.push(uni);
                }).then(() => {
                    setUnicorns(unis);
                }).catch((err) => console.error(err));
            }
        } else {
            unis.push(uni);
        }
    }
})

这是如何工作的?它获取所有的独角兽文档并迭代然后检查文档是否具有所有者的 UID。如果是,则向 Firestore 运行另一个请求以获取该独角兽所有者的文档。如果您有任何问题,请告诉我。

编辑:如果一个所有者拥有多个独角兽,那么您肯定不想一次又一次地获取同一所有者的数据。因此,将其添加到本地对象中,并在向 Firestore 发出请求之前检查是否已经获取了该所有者的数据。上面更新的相同代码。

【讨论】:

    猜你喜欢
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多