Firestore - 从文档中获取特定字段
Posted
技术标签:
【中文标题】Firestore - 从文档中获取特定字段【英文标题】:Firestore - get specific fields from document 【发布时间】:2018-09-04 02:56:18 【问题描述】:我需要什么:
我想在 Firestore 中保存文章或笔记及其各自的字段:
标题 内容(文本或段落) 创建日期 所有者(与其他人分享该文章 以及可以编辑它们的人:https://firebase.google.com/docs/firestore/solutions/role-based-access)但是当我显示文章列表时,我不需要“内容”字段(以节省带宽)。我已经读过(也许我错了),无法使用 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() 等待而不是像我一样嵌套查询?
有没有更好的方法来通过一次查询或更有效地获取文章及其内容?一些提示或想法?
非常感谢您!
【问题讨论】:
你当前的代码有什么问题? @FrankvanPuffelen 我改进了解释。代码正常工作。我对做好事只有存在主义的怀疑。 喜欢评论“存在的怀疑”精彩 【参考方案1】:Firebase 托管是您处理文章等静态内容的最佳选择。例如,如果您查看AMP-html,它们强烈支持超快速页面加载并突出边缘缓存的好处。 Firebase 托管地址为 advertised to also support global edge caching。
Firestore 和 Firebase 实时数据库是数据库引擎。这些不是提供文章的合适工具。
【讨论】:
谢谢!但这不仅适用于文章。这是为了笔记和其他东西嘿嘿:) 我明白了。原来的问题变了。希望我能够为您节省一些时间。 ...说真的,文章应该是静态的,带有静态 URL。这并不是说某些<aside>
的内容在上完主菜后无法加载。
对不起,也许我用“文章”这个词让你有点困惑。我称之为私人笔记。只有您可以在仪表板中看到带有标题和内容(所见即所得)的笔记。稍后我将添加与其他用户共享它们。不过还是谢谢! =)
? 这实际上是一个巨大的区别。我花了整整一周的时间来思考/弄清楚超快速加载和可索引(搜索/url 驱动)静态内容与数据库驱动(参数化/参数化)Web 应用程序(类似于 AMP-HTML 的荒谬)的重要性。我基本上说的是小心不要过度设计。 KISS 原则...
无论是文章还是笔记,在这里都无关紧要:-)【参考方案2】:
这两种方法都没有比另一种更好。但是有一些关键的区别。
嵌套读取时,第二次读取仅在第一次读取完成后开始。当您使用Promise.all()
时,两个读取同时开始,因此可以(部分)并行运行。
另一方面:当您使用Promise.all()
时,您的完成处理程序(您在then()
中运行的代码)在两个文档都加载之前不会执行。如果嵌套调用,则可以在加载第一个文档后更新 UI。
最后,差异可能很小。但由于它们可能对您的用例很重要,因此请衡量结果并查看最适合您的方法。
【讨论】:
在 UI 中,我会显示一个加载图标,直到我从两个查询(文章及其内容)中获得数据为止。因此我认为最好将它们与 Promise.all() 并行使用。我将尝试这两种方法中的哪一种更快/更有效。谢谢! :)【参考方案3】:根据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').`);
);
【讨论】:
我认为这仅适用于 Google Cloud 和 Node.js 包:P 两个或多个字段有机会吗? @harshadnarkhede 是的,只需用逗号分隔您想要的任何列名的列表。接口是select(...field: (string | FieldPath)[])
,所以例如这可以工作:select('field1', 'field2', 'another_field', 'and-a-fourth')
。【参考方案4】:
为了从 Firestore 文档(版本 9)输出单个字段 - 例如文章集合中的“标题”,您可以使用以下代码 sn-p:
const q = query(collection(db, 'articles'))
let results = [];
await getDocs(q);
results = getLocation.docs.map((doc) => doc.data()['title']);
results.sort()
结果数组将仅包含标题字段,按字母顺序排序 (请注意,您必须引用 Firestore 数据库并从 Firestore 导入“getDocs”、“query”和“collection”模块)
【讨论】:
以上是关于Firestore - 从文档中获取特定字段的主要内容,如果未能解决你的问题,请参考以下文章
获取具有等于flutter中特定字符串的字段的Firestore文档
如何从flutter中的firestore文档字段中获取数据?
如何在 Swift 中从 Cloud FireStore Firebase 访问特定字段
Swift - 从随机创建的文档 ID 中获取字段(Firestore)
Flutter:使用 Streambuilder<QuerySnapshot> 时如何在 firestore 中获取特定文档