Firestore - 从文档中获取特定字段

时间:2018-03-26 03:13:01

标签: javascript firebase google-cloud-firestore

我需要什么:

我想在Firestore中保存文章或备注及其各自的字段:

但是当我显示文章列表时,我不需要“内容”字段(以节省带宽)。我已经读过(也许我错了),不可能通过Firestore查询文档中的特定字段。

如果从文章中获取特定列(没有其内容)是正常的SQL,那将是:

SELECT title, creation_date, ...
FROM table_name;

所以我选择将两个根级别集合的内容分开(用于灵活性和可伸缩性)

我目前的结构:

文章集:

  - `articles` [collection]
    - `ARTICLE_ID` [document]
      - `creatorId` [field]
      - `title` [field]
      - `date` [field]
      - `owners` [obj field]
          - {user1_id}: true
          - {user2_id}: true
          ...

内容集合:

  - `contents` [collection]
    - `{ARTICLE_ID}` [document]
      - `content` [field]

实时获取文章列表:

firebase.firestore().collection('articles')
  .where(`owners.${user.uid}`, '==', true)
  .onSnapshot(querySnapshot => {
    const articles = []
    querySnapshot.forEach((doc) => {
      articles.push({
        id: doc.id,
        ...doc.data()
      })
    })
    // do something with articles array
  })

要在另一个视图中显示并获取整篇文章的内容:

const db = firebase.firestore()
const articleRef = db.collection('articles').doc(articleId)
const contentRef = db.collection('contents').doc(articleId) // same Id as article

articleRef.get().then(articleDoc => {
  if (articleDoc.exists) {
    contentRef.get().then(contentDoc => {
      if (contentDoc.exists) {
        const article = {
          ...articleDoc.data(),
          ...contentDoc.data()
        }
        // full article obj
      }
    })
  } 
})

我的问题

  • 你认为最好同时做两个查询(getArticle和getContent)并等待Promise.all()而不是像我那样嵌套查询吗?

  • 是否有更好的方法可以通过一个查询或更高效的方式获取文章及其内容?一些提示或想法?

非常感谢你!

3 个答案:

答案 0 :(得分:5)

这两种方法都没有比其他方法更好。但是有一些关键的区别。

  1. 嵌套读取时,第二次读取仅在第一次读取完成后开始。当您使用Promise.all()时,两个读取同时开始,因此可以(部分)并行运行。

  2. 另一方面:当您使用Promise.all()时,您的完成处理程序(您在then()中运行的代码)不会执行,直到两个文档都已加载。如果嵌套调用,则只需在加载第一个文档后更新UI。

  3. 最后,差异可能很小。但由于它们对您的用例可能很重要,因此请测量结果,看看哪种方法最适合您。

答案 1 :(得分:1)

根据Firestore Query.select文档,您应该可以选择所需的字段。

let collectionRef = firestore.collection('col');
let documentRef = collectionRef.doc('doc');

return documentRef.set({x:10, y:5}).then(() => {
  return collectionRef.where('x', '>', 5).select('y').get();
}).then((res) => {
  console.log(`y is ${res.docs[0].get('y')}.`);
});

答案 2 :(得分:0)

对于静态内容(例如文章),Firebase Hosting是您最好的选择。例如,如果你看一下AMP-HTML,他们会强烈地说明超快页面加载的情况并强调边缘缓存的好处。 Firebase托管是advertised to also support global edge caching

Firestore和Firebase实时数据库是数据库引擎。这些不是提供文章的适当工具。