我知道这个标题听起来像是我应该使用in
操作符。但是,如果firebase对单个查询上的多个in
没有限制,就会出现这种情况。
我正在制作一个简单的一对一消息传递web应用程序,收集我所有的聊天记录。那里的每个文档代表一条消息。这是我在一个文档中的数据结构
{
"content": "hello",
"sender": "sender ID",
"receiver": "receiver ID",
"timestamp": "SOME TIMESTAMP"
}
所以我想检索我(登录用户)sender
或receiver
的所有文档,而我当前打开的聊天是sender
或receiver
我不知道我是否说清楚了。如果firebase允许在单个查询中使用两个in
,则可以通过以下方式实现上述目标:-
query(
chatsRef,
where("sender", "in", [myID, partnerID]),
where("receiver", "in", [myID, partnerID]),
orderBy("timestamp")
)
在MySQL中,代码看起来像这样:
SELECT * FROM messages
WHERE (sender = {$myID} AND receiver = {$partnerID})
OR (sender = {$partnerID} AND receiver = {$myID}) ORDER BY timestamp)
Firebase声称in
操作符是逻辑OR
和not-in
是逻辑AND
,但不让我们将它们组合在一个查询中,这从我的pov
很奇怪然而,我已经尝试在单个查询中组合多个==
操作符用于同一字段,但这一个也不起作用。下面是代码:
query(
chatsRef,
where("sender", "==", myID),
where("receiver", "==", partnerID),
where("sender", "==", partnerID),
where("receiver", "==", myID),
orderBy("timestamp")
)
所以如果有人能想出任何解决办法,我将不胜感激。即使它需要重新构造我的数据(只要它不超过我的单个文档大小,我可以有效地使用firebase的快照功能)
[注:我使用的是ReactJS;如果它很重要的话]
您的SQL查询跨多个字段执行OR条件,这在Firestore中目前是不可能的。所以没有办法将这个查询映射到Firestore。
in
映射(即使Firestore在两个字段上允许in
)是不一样的,因为它也允许SQL不允许的组合:sender == {$myID} AND receiver == {$myID}
和sender == {$partnerID} AND receiver == {$partnerID}
。
您的最后一个查询在所有条件下执行和AND
,这将永远不会匹配任何结果,因为单个字段永远不能同时匹配两个不同的值。
我通常做的是在文档中添加一个额外的字段,其中以可靠的顺序(即按字母顺序)包含参与者的uid。例如,如果我们是参与者,我们的uid是Pratik
和Frank
:
participantsUIDs: "Frank_Pratik"
如果此字段中的uid按字母顺序排列,那么无论谁发送消息和谁接收消息,该值都将始终相同。
因此,与sender
和receiver
字段不同,这丢失了参与者角色的知识,但它确实将它们置于可预测的顺序中,这意味着您也可以可靠地查询具有两个特定参与者的文档。
您也可以为参与者使用数组字段,只要您确保项目也是可预测的顺序:
participants: ["Frank", "Pratik"]
在这样的字段上,您也可以使用==
运算符,只要您以相同的顺序传递完全相同的值。