【问题标题】:How to make a dynamic 'where' query to firestore如何对firestore进行动态“where”查询
【发布时间】:2020-06-29 21:28:26
【问题描述】:

我的收藏“abc”如下所示:

abc
  doc1: {
    users: {
      uid1: {
        gender: 'm',
        age: '99'
      },
      uid2: ...
      uid3: ...
      ...
    }
  },
  doc2: {
    ...

现在我想在用户中找到所有具有特定 uid 键的文档。 (我从云函数内部查询)

const uid = context.params.uid

我尝试了以下查询:

db.collection('abc').where(`users[${uid}]`, '>', '').get()
db.collection('abc').where(`users.${uid}`, '>', '').get()
db.collection('abc').where(`users[${uid}].gender`, '>', '').get()
db.collection('abc').where(`users.${uid}.gender`, '>', '').get()

它们会在函数控制台中导致错误,指出它不是有效的字段路径。所以我也尝试了这些

db.collection('abc').where(new admin.firestore.FieldPath(`users[${uid}]`), '>', '').get()
db.collection('abc').where(new admin.firestore.FieldPath(`users[${uid}].gender`), '>','').get()
db.collection('abc').where(new admin.firestore.FieldPath(`users.${uid}`), '>', '').get()
db.collection('abc').where(new admin.firestore.FieldPath(`users.${uid}.gender`), '>', '').get()

这也失败了。

这是否意味着无法进行动态 where 查询?或者我该如何正确地做到这一点?我应该以不同的方式构建数据吗?怎么样?

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

    第一个示例似乎在语法上被破坏了:

    db.collection('abc').where(`users[${uid}]`, '>', '').get()
    

    我想你正在寻找:

    db.collection('abc').where('users.' + uid, '>', '').get()
    

    Firestore 在处理文档中重复的嵌套值方面相当有 limited support。虽然 可以像您所拥有的那样对地图进行建模,但您可能希望查看一些替代数据模型。


    如果您希望能够查询包含特定 UID 的文档,我建议您在数据结构中添加一个仅包含 UID 的数组字段:

    doc1: {
      uids: ['uid1', 'uid2', 'uid3']
    }
    

    现在您可以use the array-contains operator 查找与某个 UID 关联的所有文档。

    db.collection('abc').where('uids', 'array-contains', 'uid1')
    

    您可以对所有要进行相等检查的字段执行相同的操作。您实际上是将您拥有的关联数组转换为多个数学集。


    如果您想执行范围查询,就像您尝试在年龄上做的那样,您必须将用户存储在每个文档的子集合中。

    abc // collection
      doc1: { // document
        users: { // collection
          uid1: { // document
            gender: 'm',
            age: '99'
          },
          uid2:  // document
          uid3:  // document
          ...
        }
      },
      doc2: { // document
        ...
    

    使用此结构,您可以查询子集合(或所有users 子集合),这允许再次进行范围查询(因为此时age 不是重复字段)。

    【讨论】:

    • 感谢您的回答。所以用 where 查询绝对不可能?然后我会按照你的方法去。由于查询问题,重构为一组地图users: [ { uid: abc, gender: m, age: 99 } ] 可能也不好?
    • 我在回答顶部的第一个问题上添加了更多内容。
    • 我一直在 'update()' 中使用动态路径,所以我假设它们也可以与 'where()' 一起使用...
    • 感谢您提供更多信息。我不打算在年龄字段上使用范围查询。我只在查询中包含“年龄”,因为我认为“>”可能只适用于字符串/数字,但不适用于地图。我会按照你写的来实现它! ?
    猜你喜欢
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多