Firestore的使用包含多个字段

时间:2018-11-01 05:56:15

标签: android google-cloud-firestore

我有一个即将推出的视频游戏应用。一个游戏发行版可以在多个平台上发行。听说Firestore在如何检索数据方面比Firebase实时数据库灵活得多。我坚持如何检查发布集合中的游戏发布文档是否包含用户选择的平台,以便该应用可以显示在他的平台上发布的游戏。

这是我目前拥有的

platforms是一个包含平台ID的Integer列表

  databaseReference.collection(getRegionNode())
            .whereEqualTo("m_y", monthFilter)
            .whereArrayContains("platforms", platforms)
            .orderBy("date", Query.Direction.ASCENDING).get().addOnCompleteListener(listener);

这是游戏发行文档的示例:

   1369: { 
        "src": "Images/dead.png",
        "name": "red dead 2",
        "date": 2018-10-26,
        "region": worldwide,
        "platforms": "[12, 13, 54]"
    }

例如,假设用户只想显示平台12和13的游戏,我想要一个查询,该查询检查并检索12和13在其 平台 中的所有发布文档/ strong>列表。谢谢!

1 个答案:

答案 0 :(得分:1)

Firestore查询的whereArrayContains(String field, Object value)

  

创建并返回带有附加过滤器的新查询,该过滤器的文档必须包含指定的字段,该值必须是一个数组,并且该数组必须包含提供的值。

根据您的注释,作为此方法的第二个参数传递的platforms对象的类型为array。您实际上在做什么,您正在platforms属性中搜索,该属性是array类型的数组,这是不可能的,因为数据库中的platform数组包含数字:

"platforms": "[12, 13, 54]"

数组。这样的查询:

databaseReference.collection(getRegionNode())
        .whereEqualTo("m_y", monthFilter)
        .whereArrayContains("platforms", 12) //Passed a number as the second argument
        .orderBy("date", Query.Direction.ASCENDING).get().addOnCompleteListener(listener);

可以正常工作,因为我们正在platforms数组中搜索一个数字。另请注意,如果您打算使用此查询之王,则需要index。有关如何创建索引,请从此 post 中查看我的答案。

即使您使用上述查询,也只能使用一个whereArrayContains()方法调用来过滤项目。如果您将使用多个,则将发生以下错误:

  

原因:java.lang.IllegalArgumentException:无效的查询。查询仅支持具有单个包含数组的过滤器。

如果需要在多个平台上进行过滤,则需要通过为拥有的每个平台创建一个属性并链接whereEqualTo()方法调用来更改数据库结构的逻辑。我知道这听起来有些怪异,但这就是Cloud Firestore的工作方式。

您的模式应为:

1369: { 
    "src": "Images/dead.png",
    "name": "red dead 2",
    "date": 2018-10-26,
    "region": worldwide,
    "platformsOne": 12,
    "platformsTwo": 13,
    "platformsThree": 54
}

要查找平台121354的所有游戏,您应该使用类似以下的查询:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query query = rootRef.
    .whereEqualTo("platformsOne", 12)
    .whereEqualTo("platformsTwo", 13)
    .whereEqualTo("platformsThree", 54);