Firebase中的高级多重搜索查询

时间:2016-12-12 08:54:57

标签: firebase firebase-realtime-database nosql

这是我的Firebase数据库" / articles",里面有很多文章。用户可以(使用他/她自己的文章)列出对应于特定条件的其他文章。为了使文章能够通过查询测试,它必须属于用户的文章列在" tradableCategories"内的类别,同时该文章也需要有用户的权限。文章" tradableCategories"。

中的文章类别

这是数据库结构:

"articles": {
  "article1": {
    "title": "Car",
    "category": "vehicles",
    "owner": "user1",
    "tradableCategories": {
      "furnishings": true,
      "other": true,
      "vehicles": true
    },
    "category_tradableCategories": {
      "vehicles_furnishings": true,
      "vehicles_other": true,
      "vehicles_vehicles": true
    }
  },
  "article2": {
    "title": "Bike",
    "category": "vehicles",
    "owner": "user2",
    "tradableCategories": {
      "furnishings": true,
      "other": true
      "vehicles": true,
    },
    "category_tradableCategories": {
      "vehicles_furnishings": true,
      "vehicles_other": true,
      "vehicles_vehicles": true
    }
  },
  "article2": {
    "title": "Couch",
    "category": "furnishings",
    "owner": "user2",
    "tradableCategories": {
      "furnishings": true,
      "other": true,
      "vehicles": true
    },
    "category_tradableCategories": {
      "furnishings_furnishings": true,
      "furnishings_other": true,
      "furnishings_vehicles": true
    }
  },
  ...
}

user1拥有article1,想要查找家具,其他和车辆内的文章。那些符合条件的文章也必须查找article1的集合类别。可以使用SQL轻松完成查询:

SELECT *
FROM articles
WHERE category = ’vehicles’ /* This is article1’s category */
  AND find_in_set(category, :tradableCategories) /* :tradableCategories is a stringified, comma-separated set of article1’s tradableCategories: “furnishings,other,vehicles” */
  AND NOT owner = ‘user1’

正如您在数据库结构中看到的那样。我已经包含了另一个名为“category_tradableCategories”的对象。我在Stack Overflow上看到了各种答案,解释了如何使用两个条件组合成一个来搜索项目。这可能有效,但意味着我必须启动3个Firebase查询,因​​为我无法在tradableCategories中组合三个(或更多)不同的类别。

我担心这对Firebase来说太复杂了,但如果有任何有效的解决方案,我想要一些帮助。谢谢!

1 个答案:

答案 0 :(得分:2)

在关系数据库中,您通常首先定义数据模型以匹配您要存储的数据,然后针对应用程序的用例编写查询。在NoSQL数据库中,您通常使用逆逻辑:您列出应用程序的用例列表,然后定义数据模型以匹配这些用例。

如果Firebase的API不直接支持您要构建的查询,则通常必须更改/扩充数据模型以允许该查询。这将导致存储更多数据和更复杂的更新,但优点是您可以更快,更简单地进行读取操作。

因此,在您的场景中:您需要一个不属于当前用户的三个类别之一的文章列表。该要求的最直接映射是按字面意思存储该列表:

user_articles
  $uid
    categories_1_2_3
      articlekey1: true
      articlekey2: true

这会使查询变得微不足道:ref.child("user_articles").child(currentUser.uid).child(categories).on("child_added"...

现在这可能会使非规范化和重复有点过头了。我们需要为每个用户/类别组合单独列出。因此,包含10个用户的3个类别的文章将最终出现在60个列表中。

您更有可能希望将这些文章按类别保存在所有用户的单个列表中。例如:

articles_by_category_with_owner
  category_1
    articlekey1: uid1
    articlekey2: uid2
    articlekey3: uid1
  category_2
    articlekey1: uid1
    articlekey2: uid2
  category_3
    articlekey1: uid1
    articlekey3: uid1

现在,您可以使用ref.child("articles_by_category_with_owner").child(category).on("child_added"...获取category_1的所有文章键,然后执行“当前用户不拥有”过滤客户端。

在上面的列表中,我还删除了多个类别。这确实意味着您需要为每个类别读取一个节点。但实际上这并不像您预期​​的那么慢,因为Firebase会对这些请求进行管道处理(请参阅下面的链接)。

进一步推荐阅读/观看: