Firestore查询 - 数组包含所有

3
我的使用案例涉及使用“array-contains-all”过滤Firestore文档,我为此问题编写了名称。然而,“array-contains-any”已经存在,但它不检查数组中是否存在所有元素,而是任意一个。我很难找到内置的解决方案或找到更好的方法来实现相同的结果,而不是查询所有文档(昂贵),然后在云函数中过滤结果,最后将最终数组传递给客户端之前。
举个例子,我们想知道哪些住宿网站有我们感兴趣并希望查询的所有设施。
[
    'lockable_bedroom_door',
    'private_bathroom',
    'internet',
    'desk',
    'safe_place_to_store_valuables'
]

在所有13个可用设施的数组中:

[
    'kettle',
    'microwave',
    'cooker',
    'washing_machine',
    'fully_functional_kitchen',
    'lockable_bedroom_door',
    'private_bathroom',
    'shared_bathroom',
    'internet',
    'desk',
    'common_room_lounge',
    'safe_place_to_store_valuables',
    'free_on-site_parking'
]

如何在考虑到Firestore限制和用户可能选择的设施数量的情况下实现此目标?

1
我已经向Firebase团队提出了关于这个功能的请求,希望他们能够实现。 - undefined
2个回答

5
只要您现在使用列表类型字段,就没有办法查询到您觉得高效的方式。如果将数据复制到新的映射类型字段中,则可以实现。
facilities: {
    'kettle': true
    'microwave': true
    'cooker': true
}

有了包含已知布尔值的地图,您可以像这样查询:

firestore
    .collection("your-collection")
    .where("facilities.kettle", "==", true)
    .where("facilities.microwave", "==", true)
    .where("facilities.cooker", "==", true)

1
谢谢你的回答,道格!你知道在一个查询中使用'=='运算符的where子句数量是否有限制吗?我考虑可能会有超过10个设施,用户可能希望每个住宿都包含这些设施。如果没有限制的话,那将是一个完美的解决方案,只需要你上面提到的微小改变就可以了。 - undefined
所有系统的限制都有文档记录。如果你在文档中找不到相关信息,那就意味着没有已知的限制。请访问https://firebase.google.com/docs/firestore/quotas了解更多详情。 - undefined
这是否需要我们配置Firestore来索引facilities中的字段? - undefined
还是它仍然是唯一的解决方案吗? - undefined
4
这将需要为facilities下的每个键创建一个索引....来吧Firebase...你可以做得比这更好!!! - undefined
1
我们如何动态地添加where子句? - undefined

0
也许这个可以帮到你,我为这个问题实施了一个解决方法。
// generate all every combinasons possibles
fun generateTags(list: List<String>): List<String> {
    val combinations = mutableListOf<String>()

    val size = list.size
    val maxMask = (1 shl size) - 1

    for (mask in 1..maxMask) {
        val current = mutableListOf<String>()
        for (i in 0 until size) {
            if ((mask and (1 shl i)) != 0) {
                current.add(list[i])
            }
        }
        combinations.add(current.joinToString("_"))
    }

    return combinations
}

将结果保存在一个数组字段中,然后在查询中使用WhereArrayContains(Field, list.joinToString("_"))。列表中的项目排序很重要。
对不起,我的英语不好,我只会说法语。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接