【问题标题】:Firebase NodeJS SDK: Query by value on nested objectFirebase NodeJS SDK:按嵌套对象的值查询
【发布时间】:2021-02-10 22:48:58
【问题描述】:

我有一个结构如下的集合/表:

{
  UsedPromos: {
    "userid_1": {
      "product_1_1": "promo_1_1",
      "product_1_2": "promo_1_2",
      ...
      "product_1_n": "promo_1_n",
    },
    "userid_2": {
      "product_2": "promo_2"
    },
    ...
    "userid_m": {
      ...
    }
  }
}

如何查询与某些“promo_x_y”的完全匹配?到目前为止我已经尝试过了:

const admin = require("firebase-admin");
admin.initializeApp(...);
const ref = admin.database().ref("/UsedPromos");
ref.orderByValue()
  .equalTo("promo_x_y")
  .once("child_added")
  .then((snapshot) => {
    console.log(`{key: ${snapshot.key}, value: ${snapshot.val()}}`);
    return snapshot
  });

但它没有返回任何东西。

【问题讨论】:

    标签: node.js firebase firebase-realtime-database


    【解决方案1】:

    如果您要查找属于促销promo_x_y 的所有产品,则需要将您的查询调整到比您当前所做的更深一层。

    目前您正在将user_1user_2 等的值与"promo_x_y" 的值进行比较。您没有得到任何结果,因为没有条目 /UsedPromos/user_1 = "promo_x_y" 存在。

    /UsedPromosByUser/{user}/{product} = {promo} (your current structure)
    

    要解决此问题,您需要搜索单个用户的产品列表。使用下面的 sn-p 将记录具有“promo_x_y”值的每个产品。

    const admin = require("firebase-admin");
    admin.initializeApp(/* ... */);
    
    const ref = admin.database().ref("/UsedPromos");
    const userToSearch = "user_1";
    
    ref.child(userToSearch)
      .orderByValue()
      .equalTo("promo_x_y")
      .once("child_added")
      .then((snapshot) => {
        // snapshot.val() will always be "promo_x_y", so don't bother logging it.
        console.log(`${snapshot.key} uses "promo_x_y"`);
        return snapshot;
      });
    

    根据您的用例,使用"value" 事件可能会更好。

    const admin = require("firebase-admin");
    admin.initializeApp(/* ... */);
    
    const ref = admin.database().ref("/UsedPromos");
    const userToSearch = "user_1";
    
    ref.child(userToSearch)
      .orderByValue()
      .equalTo("promo_x_y")
      .once("value")
      .then((querySnapshot) => {
        const productKeys = [];
        // productSnapshot.val() will always be "promo_x_y", so don't bother logging it.
        querySnapshot.forEach((productSnapshot) => productKeys.push(productSnapshot.key));
        
        console.log(`The following products have a value of "promo_x_y" for user "${userToSearch}": ${productKeys.join(", "}`);
        return productKeys;
      });
    

    如果您要查找所有用户中使用“promo_x_y”的所有产品,则应在数据库中创建索引,而不是使用查询。

    /UsedPromosByPromo/{promo}/{user}/{product} = true
    OR
    /UsedPromosByPromo/{promo}/{product}/{user} = true
    

    您可以存储时间戳(购买时间、促销到期时间等),而不是在上述结构中使用 true

    【讨论】:

    • 是的,你提到的第三个就是我要找的那个。我需要找到具有该促销活动的用户,因此我需要在所有用户中查找。如果我设置了索引,那么索引在规则中会是什么样子以及如何从中读取?
    猜你喜欢
    • 2021-04-10
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多