【问题标题】:Advanced product filtering with Cloud Firestore使用 Cloud Firestore 进行高级产品过滤
【发布时间】:2020-04-25 00:04:29
【问题描述】:

我的产品结构是

product2: {
    allAttributes: {
        Color: ['black', 'silver'],
        model: ["hero7"],
        accessories: ["full travel kit", "2 batteries", "2 batteries + charger"],
        brand: ["GoPro"]
    }
    category: ["camping"]
    depositAmount: 1500
    depositAmountTooltip: "Fully refundable security for this product."
    displayrent: 650
    expressDeliveryCharge: 200
    id: "Ur89kjsllljVdQ8MM"
    inventory: 5
    keywords: (6)["Camping", "Outdoor", "Camera", "Electronic", "Gopro", "Action Cameras"]
    longDescription: "longdescription"
    name: "Gopro Hero 7 Black"
    pictures: (3)[{
        …}, {
        …}, {
        …}]
    rank: 4501
    subCategory: (6)["camping", "outdoor", "camera", "electronic", "gopro", "actioncamera"]
}

product1: {
    allAttributes: {
        Color: ['black', 'silver'],
        model: ["hero8"],
        accessories: ["full travel kit", "2 batteries", "2 batteries + charger"],
        brand: ["GoPro"]
    }
    category: ["camping"]
    depositAmount: 2000
    depositAmountTooltip: "Fully refundable security for this product."
    displayrent: 750
    expressDeliveryCharge: 200
    id: "Ur89kfksj1mVdQ8MM"
    inventory: 5
    keywords: (6)["Camping", "Outdoor", "Camera", "Electronic", "Gopro", "Action Cameras"]
    longDescription: "longdescription"
    name: "Gopro Hero 8 Black"
    pictures: (3)[{
        …}, {
        …}, {
        …}]
    rank: 4500
    subCategory: (6)["camping", "outdoor", "camera", "electronic", "gopro", "actioncamera"]
}

我正在查询它,

const {category, subCategory, color, brand } = req.query;
       AllProductModel.where('category', '==', category)
      .where('subCategory', 'array-contains-any', subCategory)
      .get()

现在,我无法根据 color(req.query 中的数组) 和 brand(req.query 中的数组) 属性进行查询 如何根据从客户端选择的allAttributes 在 Cloud Firestore 上查询此类产品。我不想在客户端应用程序上这样做。

我正在使用“ReactJS”和“NodeJS,Express”。

【问题讨论】:

  • 您是否已经尝试过?如果没有,我建议从firebase.google.com/docs/firestore/query-data/queries 开始。如果您已经这样做了,请编辑您的问题以包含minimum code that reproduces where you got stuck
  • @FrankvanPuffelen 嘿,感谢您的帮助。我已经浏览了 firestore 上的查询文档。我想到的一种解决方法是在我的服务器上加载 3000-4000 个文档,然后在那里过滤它们。过滤后的文件然后发送到我的前端。这可能吗?或者它将在我的服务器上放置多少负载?
  • @FrankvanPuffelen 如果不是 Firestore,您会推荐哪个数据库?我目前正在使用 GAE 部署我的应用程序(前端和后端分开),我打算切换到 GCP 云功能。

标签: node.js reactjs google-cloud-firestore


【解决方案1】:

如果product1product2 都是集合中的一个文档(例如products),那么您可以选择所有可用的银色产品,例如:

let productsRef = firebase.firestore().collection('products');
productsRef.where("allAtributes.Color", "array-contains", "silver")

上述查询使用array-contains clause


您还可以选择所有提供银色或黑色的产品:

productsRef.where("allAtributes.Color", "array-contains-any", ["silver", "black"])

这个所谓的array-contains-any子句可以:

使用 array-contains-any 运算符将同一字段上的最多 10 个 array-contains 子句与逻辑 OR 组合起来。


您可以对allAttributes 中的任何字段执行上述查询子句。但是您只能在一个字段上执行此子句。来自documentation on query limitations

每个查询只能使用一个inarray-contains-any 子句。您不能在同一查询中同时使用 inarray-contains-any

因此您可以查询所有银色或黑色的产品,您可以查询 GoPro 的所有产品,但您无法查询应用程序 GoPro 的银色或黑色产品。

如果您将品牌存储为这样的单值字段:

    "allAttributes": {
        ...
        brand: "GoPro"
    }

使用上述结构,您可以像这样查询:

productsRef
  .where("allAtributes.brand", "==", "GoPro")
  .where("allAtributes.Color", "array-contains-any", ["silver", "black"])

要获得所有有银色或黑色可供选择的 GoPro 产品,但当然此时每个产品只能属于一个品牌。


如果您的用例绝对需要在 Firestore 上无法实现的查询类型,请考虑将 Firestore 合并或替换为另一个数据库。

【讨论】:

    猜你喜欢
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    相关资源
    最近更新 更多