如何在Firestore中查询数组中的多个项目? (“数组包含”)

时间:2018-08-24 19:41:44

标签: javascript firebase google-cloud-firestore

我正在使用Firestore和Javascript(vue.js)构建一对一的聊天应用程序。

我有一个对话和一个消息文档,定义如下:

.collection(“ coversation”)。doc()

conversation: {
  participantsArray: ["id1", "id2"],
  participants: {
    id1: {
      /* details like avatar & name */
    },
    id2: {
      /* details like avatar & name */
    }
  }
}

.collection(“ coversation”)。doc(“ foo”)。collection(“ messages”)。doc()

message: {
  message: "foo"
}

这很棒,所以我现在可以像这样查询特定用户的所有对话:

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

我现在遇到的问题如下:

我想查询特定的对话,例如:

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

但是这是行不通的,因为不允许使用双重“数组包含”并引发错误消息。

目前对我有用的是像这样打两个电话:

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

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

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

它可以工作,但这是一堆代码,效率很低。

所以我的问题是:

  1. 有更好的方法吗?
  2. 如何使用“包含数组”检查多个项目?
  3. 我同时拥有一个 participantsArray 和一个 participants 字段,因为我不知道如何对对象数组进行“数组包含”。有办法还是应该同时保留两个字段?

PS: 以前,我曾经像这样查询参与者对象中的对象:

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

这是在“数组包含”存在之前提出的查询方法-但是当与orderBy结合使用时,我必须为每个用户创建一个索引,这并不是一个选择。

2 个答案:

答案 0 :(得分:3)

我找到了一种方法来查询单个对话。

由于我既有(1)个参与者的详细信息在“ 参与者”对象中,又有(2)参与者ID在“ participantsArray ”中,所以我可以查询进行如下单个对话:

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

所以我现在很高兴。但是,这三个问题仍然存在,因此,如果有人可以正确回答这些问题,他们的回答将非常有价值:)

答案 1 :(得分:0)

另一种选择是在文档中有两个字段,一个字段用于按字母顺序排列的最低用户ID(LAUID),另一个用于按字母顺序排列的最高用户ID(HAUID)。如果您在客户端上同时拥有两个用户ID,但不知道哪个是哪个ID,则可以找出两个ID中的哪个ID较大(UID2),哪个ID最小(UID1),那么您的查询将是HAUID等于UID2,其中LAUID等于UID1