部分比赛。文件至少包含搜寻参数之一

时间:2018-11-14 15:28:00

标签: firebase google-cloud-firestore

有一个Firestore集合,用于存储配方和一系列配料。我们需要找到至少包含一种成分的食谱。如何执行呢?使用Firestore可以做到这一点吗?

--- recipe1 
          |
          --- ingredients: ["salt", "pepper", "sucar"]
--- recipe2 
          |
          ---  ingredients: ["pepper"]
--- recipe3 
          |
          ---  ingredients: ["salt", "pepper"] 

如何选择其中包含“ 胡椒”的食谱?

1 个答案:

答案 0 :(得分:0)

  

这可以在Firestore吗?

是的。

  

我们需要找到包含至少一种成分的食谱。如何实现?

为了实现此功能,您应该使用数组。请在下面查看数据库架构,它可以帮助您实现这一目标:

Firestore-root
    |
    --- recipes (collection)
         |
         --- recipeId (document)
               |
               --- ingredients: ["salt", "pepper"] (array)
               |
               --- //other decipe details

要查找包含一种成分的所有食谱,您应该使用如下查询:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query query = rootRef.collection("recipes").whereArrayContains("ingredients", "salt");

这是针对Android的,但您可以通过相同的方式针对其他编程语言来实现。请参阅here更多详细信息。

但是请注意,在不对数据库进行重大更改的情况下,您不可能找到所有包含一种以上成分的食谱。 Firestore 不允许不允许链接的whereArrayContains()调用。因此,您可以获得所有仅包含一种成分成分的食谱。

编辑:根据您的评论:

  

如何选择有“胡椒粉”或“盐”的配方?

您需要知道Firestore中没有OR子句。根据我在 post 中的回答,您应该创建两个单独的查询并合并结果客户端。

编辑2:

  

100,000个可在客户端上组合的食谱。

如果这是您应用程序的用例,那么您应该以这种方式进行查询。 Firestore可大规模扩展。

  

但这是一个相当简单的查询!

就SQL数据库而言,这就是NoSQL数据库的工作方式。

  

如果您需要排除包含“糖”成分的食谱?

根据官方文档,除了没有OR子句的事实之外,还有另一个query limitation

  

带有!=子句的查询。在这种情况下,您应该将查询分为大于查询和小于查询。

因此,这是解决excludenot equal情况的方法。

  

您的链接也不能解决问题。

我的链接无法解决无法以您想要的方式解决的问题,它仅表示Firestore官方文档提供的约束。在该链接中,我还按照文档推荐的方式提供了一种解决方法。在这种情况下,您应该根据我的答案和该帖子中的信息进行尝试,并询问是否还有其他问题。

  

结果-盐和胡椒粉食谱。但是不能加盐或胡椒粉!

否,如果您创建两个单独的查询并合并结果提示端,那么您将获得所需的结果。我已经对其进行了测试,并且效果很好。

  

我知道不存在“或”。因此,我问-有解决方案吗?

是的,我上面提供的解决方案是最简单的。如果您对此不满意,则还可以考虑更改整个数据库结构,以便可以根据反向查询进行组织。您的结构应如下所示:

Firestore-root
   |
   --- salt_peper (collection)
   |     |
   |     --- recipeId (document)
   |     |     |
   |     |     --- //recipe with salt
   |     |
   |     --- recipeId (document)
   |           |
   |           --- //recipe with peper
   |
   --- salt_sugar (collection)
         |
         --- recipeId (document)
               |
               --- //recipe details

如您所见,这是数据库的另一个架构。第一个集合将为您提供所有食盐OR胡椒粉的食谱。

这种做法称为denormalization,是Firebase的常见做法。为了更好地理解,我建议您观看此视频Denormalization is normal with the Firebase Database。它用于Firebase实时数据库,但相同的原理也适用于Cloud Firestore。

此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。

我还建议您从此 post 看一下我的回答,以了解有关上述技术的利弊。