如何在Firestore中查询多个数组项?(“array-contains”)

7
我正在使用Firestore和Javascript(vue.js)构建一种一对一的聊天应用程序。
我已经定义了一个会话和消息文档,如下所示: .collection("conversation").doc()
conversation: {
  participantsArray: ["id1", "id2"],
  participants: {
    id1: {
      /* details like avatar & name */
    },
    id2: {
      /* details like avatar & name */
    }
  }
}

.collection("coversation").doc("foo").collection("messages").doc()

可以翻译成:在“coversation”集合中的“foo”文档下的“messages”子集合中的文档。
message: {
  message: "foo"
}

太好了,现在我可以这样查询特定用户的所有对话:

db.collection('conversations').where("participantsArray", "array-contains", userId)

我现在遇到的问题如下:
我想查询特定的对话,例如:

我要查询特定的对话:

db.collection('conversations')
  .where("participantsArray", "array-contains", userId)
  .where("participantsArray", "array-contains", chatpartnerId)

但是这种方法行不通,因为不允许使用双重的“array-contains”,会导致错误信息。

目前对我有效的方法是进行两次调用,如下所示:

db.collection('conversations')
  .where(`participantsArray`, '==', [userId, chatpartnerId])

db.collection('conversations')
  .where(`participantsArray`, '==', [chatpartnerId, userId])

然后检查这些查询是否返回了一个对话。如果是,我就使用该对话添加一条消息;否则,我创建一个新的对话。

它能够正常工作,但代码量很大且效率低下。

因此我的问题是:

  1. 有更好的方法吗?
  2. 如何执行“array-contains”以检查多个项目?
  3. 我有一个 participantsArray 和一个 participants 字段,因为我没有找到如何在对象数组上执行“array-contains”。有办法吗?还是应该保留这两个字段?

PS: 之前,我像这样在参与者对象中查询对象:

db.collection("conversations").where(`participants.${userId}.id`, "==", userId)

"array-contains"出现之前,这是查询的建议方式 - 但是当与orderBy结合使用时,我必须为每个用户创建一个索引,这不是一个真正的选择。

2个回答

4
我发现了一种查询单个对话的方法。由于我已经拥有(1)包含详细信息的参与者对象和(2)包含参与者ID的“participantsArray”,因此可以按以下方式查询单个对话:
db.collection('conversations')
      .where(`participants.${userId}.id`, "==", userId)
      .where(`participants.${chatPartnerId}.id`, "==", chatPartnerId)

所以,目前我很高兴。然而,这三个问题仍然存在,如果有人能够正确回答它们,他们的答案将非常有价值 :)

1
非常感谢,Pascal。这似乎确实是正确的方法。对于任何有兴趣的人,这个Firebase官方视频非常有用,可以了解数组、映射和子集合的使用时机:https://www.youtube.com/watch?v=o7d5Zeic63s - Kqtr

0
一个替代方案是在文档中有两个字段,一个用于最小字母顺序的用户ID(LAUID),另一个用于最大字母顺序的用户ID(HAUID)。如果您在客户端上拥有两个用户ID,但不知道哪个是哪个,您可以找出这两个ID中哪个更大(UID2)和哪个更小(UID1),然后您的查询将是where HAUID等于UID2和where LAUID等于UID1。

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