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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49483406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:22:56  来源:igfitidea点击:

Firestore - get specific fields from document

javascriptfirebasegoogle-cloud-firestore

提问by BlackCode

What I need:

我需要的:

I want to save articles or notes in Firestore with their respective fields:

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

But when I show the list of articles I don't need the "content" field (to save bandwidth). I've read that (maybe I'm wrong), it is not possible to make a query to get only specific fields from a document with Firestore.

但是当我显示文章列表时,我不需要“内容”字段(以节省带宽)。我已经读过(也许我错了),无法使用 Firestore 进行查询以仅从文档中获取特定字段。

If it were normal SQL to obtain specific columns from articles (without its content) It would be something like:

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

SELECT title, creation_date, ...
FROM table_name;

So I've opted to separate the content for two root-level collections (for flexibility and scalability)

所以我选择将两个根级集合的内容分开(为了灵活性和可扩展性)



My current structure:

我目前的结构:

Articles collection:

文章收藏:

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

Contents collection:

内容收集:

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

To get articles list in realtime:

实时获取文章列表:

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

To show in another view and get the entire article with its content:

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

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


My questions

我的问题

  • Do you think it's better to do two queries (getArticle and getContent) at the same time and wait with Promise.all() instead of nesting the querys like I do?

  • Is there a better way to get the article and its content with one query or more efficiently? Some tips or ideas?

  • 您认为最好同时执行两个查询(getArticle 和 getContent)并使用 Promise.all() 等待而不是像我一样嵌套查询?

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

Thank you very much in advance!

非常感谢您提前!

采纳答案by Frank van Puffelen

Neither approach is pertinently better than the other. But there are a few key differences.

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

  1. When you nest the reads, the second read only starts after the first read has completed. When you use Promise.all()both reads start at the same time, so can (partially) run in parallel.

  2. On the other hand: when you use Promise.all()your completion handler (the code you run in then()) won't execute until both documents have loaded. If you nest the calls, you can update the UI after just the first document has loaded.

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

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

In the end, the differences are likely to be small. But since they may be significant to your use-case, measure the results and see what works best for you.

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

回答by abraham

According to the Firestore Query.selectdocumentation you should be able to select the fields you want.

根据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')}.`);
});

回答by Ronnie Royston

Firebase Hosting would be your best bet for static content such as articles. If you look at AMP-HTMLfor example, they strongly make the case for ultra-fast page loads and highlight benefits of edge caching. Firebase hosting is advertised to also support global edge caching.

Firebase Hosting 是静态内容(如文章)的最佳选择。例如,如果您查看AMP-HTML,它们强烈支持超快页面加载并突出边缘缓存的优势。Firebase 托管被宣传为还支持全球边缘缓存

Firestore and Firebase Realtime Database are database engines. These are not the proper tool for serving up articles.

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