Firebase 查询类别中的产品(数据库设置和最佳实践)

Posted

技术标签:

【中文标题】Firebase 查询类别中的产品(数据库设置和最佳实践)【英文标题】:Firebase Query for Products in Categories (database setup and best practice) 【发布时间】:2020-12-25 13:22:16 【问题描述】:

TL;DR 产品有多个类别。 视图应仅显示分配了该类别的所有子类别和产品。

如何设置数据库和查询?


我目前正在学习 Vue 和 Firebase,来自 C# 和 SQL 背景,我需要一些关于 noSQL 方面的帮助和建议。

编辑:类别和产品是两个独立的集合(目前)。

我有产品,可以有多个类别(参见产品 5)

products: 
  prod1-id: 
    name:'apple-type-A',
    price: 2
    cats: cat1-id
  
  prod2-id: 
    name:'apple-type-B',
    price: 2.5
    cats: cat1-id
  
  prod3-id: 
    name:'banana-type-A',
    price: 1.6
    cats: cat2-id
  
  prod4-id: 
    name:'banana-type-B',
    price: 1.9
    cats: cat2-id
  
  prod5-id: 
    name:'smoothie',
    price: 5,
    cats: [cat2-id, subCat1-id, subCat2-id]
  

这些类别是一棵树。

categories: 
  cat1-id: 
    name: 'fruits',
    subCat1-id: 
      name: 'apple'
    
    subCat2-id: 
      name: 'banana'
    
  ,
  cat2-id: 
    name: 'MySmooth'
  

客户应该会看到第一棵树。

着陆页应该只显示类别树的第一个深度和每个没有类别的产品(可能添加一个名为“无类别”的类别)。

当您单击一个类别时,应显示所有具有此类别的子类别和产品。

这样一直持续到最深的分支。

我试图勾勒出我的想法:


查看

对于编程,我使用 Vue、vuex 和 vuexfire 以及作为框架 Vuetify。

我有完整的产品管理设置,但我不知道如何查询此视图。

我的想法是重复使用我已经拥有并且工作正常的<v-card v-for="p of products">

但这仅显示产品,而不是类别。如何将类别混在一起?

查询

使用 vuexfire 这很简单。

bindSoldProducts: firestoreAction(( bindFirestoreRef ) => bindFirestoreRef('products', productsColl.where('isSold', '==', true))

但我如何才能让现在并排显示的类别和产品?

我已经开始通过查询将产品放在一起,但不知道如何将类别组合在一起:

firebase.firestore.collection('products').orderBy('name', 'asc').onSnapshot(snap => 
  const productsArray: any = []

  snap.forEach(doc => 
    const product = doc.data()
    product.id = doc.id
    productsArray.push(product)
  )

  store.commit('setAllProducts', productsArray)
)

我需要以不同的方式构建我的数据库吗?

我是否只是查询产品并使用“一些 js 逻辑/魔术”来显示类别?但是我如何才能获得意见。

firebase 的集合组查询是否正确?如果是,怎么做?

请指教

【问题讨论】:

没有深入,我立即看到一个问题。 [cat2-id, subCat1-id, subCat2-id] 你在一个数组中混合了两种不同的“东西”。你如何区分一个和另一个(猫与子猫)? @Jay nono,我应该将它们命名为“cat3”和“cat4”。我只是想解释一下,类别可以像产品一样属于类别本身。 我建议重新考虑这个问题是如何提出的。您已经得到了 cmets 和一些似乎与该问题不相符的答案。缩短并澄清它,然后我们将看看。 @Jay,我知道,但到目前为止,这里的一切都有点帮助。目前我有一个解决方案,当我准备好订阅时,我会在这里发布 【参考方案1】:

在所有类别中尝试 for 并获得成果:

const categories = 
 "cat1-id": []


Object.keys(categories).forEach(cat => 
   const res = db.collection('products').where('cats', 'array-contains', cat).get()
   // Resolve and put (push) in categories[cat]
)

见:https://firebase.google.com/docs/firestore/query-data/queries

【讨论】:

当库存发生变化时,这是否仍会保持实时更新? 使用get方法你不会看到变化,在顶部定义变量类别并开始观察变化并以相同的方式将它们分配到变量中 好的,这可以获取产品,但是我如何获取产品和子类别?我是否必须对两者都运行查询并将所有内容加入一个数组中,以便我可以显示它的内容? 根据我对您的数据结构的理解,“products”中的“cats”是一个包含类别和子类别的数组,因此查询适用于类别和子类别。您可以为类别和子类别创建变量。如果您要观察所有内容,这在您的应用程序中可能会非常繁重,因此我建议您使用良好的做法来仅观察用户需要的内容 也许我们这里有不同的理解:“Categories”是一个集合,“products”是一个单独的集合。我在我的产品中提到了这些类别。树结构仅在“类别集合”中。我会尝试一下,稍后根据我发现的内容编辑我的帖子。【参考方案2】:

我正在写我的回复,因为它太长了,无法发表评论。

如果我正确理解了您的用例,您希望拥有一个数据库结构,其中包含产品列表及其各自的类别,它们将同时并排显示在您的 Vue 应用程序视图中。

虽然我不是 Vue 专家,但我可以建议为您的 Cloud Firestore 数据库使用以下结构:Products/product/categories/category,转换为 集合/document/collection/document

在Cloud Firestore data model 中,您可以在另一个集合中拥有一个集合,这称为子集合。例如,您可以有 Products/fruits/Categories/banana 并且在 banana 文档中您可以有 typeprice em> 或 id 字段等。

然后,您可以使用Collection group queries 从集合组而不是单个集合中检索文档。集合组由具有相同 ID 的所有集合组成。默认情况下,查询从数据库中的单个集合中检索结果。

例如,您可以通过向每个 product 添加一个 Categories 子集合来创建一个 categories 集合组,然后从每个产品的类别中检索结果立即子集合,比方说 bananas

const querySnapshot = await db.collectionGroup('categories').where('productName', '==', 'banana').get();
querySnapshot.forEach((doc) => 
  console.log(doc.id, ' => ', doc.data());
  // Banana from Mexico, Banana from Honduras, etc.
);

在使用集合组查询之前,不要忘记创建an index that supports your collection group query。您可以通过错误消息、控制台或 Firebase CLI 创建索引。

【讨论】:

不抱歉,错了。我将编辑我的问题并尝试更好地解释它:集合 1:产品集合 2:类别

以上是关于Firebase 查询类别中的产品(数据库设置和最佳实践)的主要内容,如果未能解决你的问题,请参考以下文章

Flutter如何根据某个值从firebase对列表进行分组

减少查询中的结果数

如何从 Flutter 中的 Firebase 实时数据库中按 categoryId 获取产品?

sql 查询以检索Magento中的所有产品ID及其所属的类别。

MYSQL - 获取所有选定类别中的行

SQl查询:统计分类中的产品,一次统计1个分类,不统计其他分类