来自the docs:
您还可以链接多个where()方法以创建更具体的查询(逻辑AND)。
如何执行OR
查询?
示例:
status
为open
或upcoming
status == open
或createdAt <= <somedatetime>
答案 0 :(得分:14)
OR
不受支持,因为服务器难以扩展它(需要将状态保持为重复数据删除)。解决方法是发出2个查询,每个条件一个,以及客户端上的重复数据删除。
答案 1 :(得分:2)
我没有&#34;状态&#34;字段,但与状态相关的字段,根据请求将其更新为true或false,如
{ name: "a", status_open: true, status_upcoming: false, status_closed: false}
但是,请检查Firebase云功能。您可以更改功能侦听状态,更新与状态相关的属性,如
{ name: "a", status: "open", status_open: true, status_upcoming: false, status_closed: false}
一个或另一个,您的查询可能只是
...where('status_open','==',true)...
希望它有所帮助。
答案 2 :(得分:2)
借助recent addition of IN queries,Firestore支持“同一字段上具有逻辑 OR 的多达10个相等子句”
(1)的可能解决方案是:
documents.where('status', 'in', ['open', 'upcoming']);
请参见Firebase Guides: Query Operators | in
and array-contains-any
答案 3 :(得分:0)
您可以使用rxjs merge运算符绑定两个Observable。 这里有一个例子。
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/merge';
...
getCombinatedStatus(): Observable<any> {
return Observable.merge(this.db.collection('foo', ref => ref.where('status','==','open')).valueChanges(),
this.db.collection('foo', ref => ref.where('status','==','upcoming')).valueChanges());
}
然后您可以使用上述方法订阅新的Observable更新:
getCombinatedStatus.subscribe(results => console.log(results);
我希望这可以帮助你,来自智利的问候!!
答案 4 :(得分:0)
建议也为状态赋予价值。
前。
{ name: "a", statusValue = 10, status = 'open' }
{ name: "b", statusValue = 20, status = 'upcoming'}
{ name: "c", statusValue = 30, status = 'close'}
您可以ref.where('statusValue', '<=', 20)
进行查询,然后找到'a'
和'b'
。
这可以节省您的查询成本和性能。
顺便说一下,它并没有解决所有情况。
答案 5 :(得分:0)
我们现在有同样的问题,幸运的是,我们的唯一可能的值是A,B,C,D(4),因此我们必须查询类似A || B,A || C,A ||的值。 B || C,D等
大约几个月前,firebase支持一个新查询array-contains
,因此我们要做的是制作一个数组,并对数组的OR值进行预处理
if (a) {
array addObject:@"a"
}
if (b) {
array addObject:@"b"
}
if (a||b) {
array addObject:@"a||b"
}
etc
我们对所有4!
值或存在许多组合的情况进行此操作。
我们可以简单地检查查询[document arrayContains:@"a||c"]
或我们需要的任何类型的条件。
因此,如果某些内容仅符合我们4个条件(A,B,C,D)中的条件A
,则其数组将包含以下文字字符串:@["A", "A||B", "A||C", "A||D", "A||B||C", "A||B||D", "A||C||D", "A||B||C||D"]
然后对于任何OR
组合,我们都可以根据需要搜索array-contains
(例如“ A || C”)
注意:仅当您有几个可能的值要进行“或”比较时,这才是合理的方法。
有关Array-contains here的更多信息,因为它是Firebase文档的新功能
答案 6 :(得分:0)
不支持
但是,如果需要,您可以在代码中完成
例如:如果我要查询的商品(尺寸等于Xl或XXL:并且性别是男性)
productsCollectionRef
//1* first get query where can firestore handle it
.whereEqualTo("gender", "Male")
.addSnapshotListener((queryDocumentSnapshots, e) -> {
if (queryDocumentSnapshots == null)
return;
List<Product> productList = new ArrayList<>();
for (DocumentSnapshot snapshot : queryDocumentSnapshots.getDocuments()) {
Product product = snapshot.toObject(Product.class);
//2* then check your query OR Condition because firestore just support AND Condition
if (product.getSize().equals("XL") || product.getSize().equals("XXL"))
productList.add(product);
}
liveData.setValue(productList);
});
答案 7 :(得分:0)
对于Flutter dart语言,请使用以下代码:
request.prototype.on('error', (e) => doSomething())`
答案 8 :(得分:0)
这不能解决所有情况,但是对于“枚举”字段,您可以通过为每个枚举值创建一个单独的布尔字段,然后为每个值添加where("enum_<value>", "==", false)
来模拟“ OR”查询不是您想要的“ OR”子句的一部分。
例如,考虑您的第一个所需查询:
- 给我所有字段状态为打开或即将到来的文档
您可以通过将status: string
字段拆分为多个布尔字段(每个枚举值一个)来实现此目的:
status_open: bool
status_upcoming: bool
status_suspended: bool
status_closed: bool
要执行“状态为打开或即将发生的状态”查询,请执行以下操作:
where("status_suspended", "==", false).where("status_closed", "==", false)
这是如何工作的?好吧,因为它是一个枚举,所以您知道必须为其中一个值分配true
。因此,如果您可以确定所有 other 值都不与给定条目匹配,那么通过推导,它必须与您最初寻找的值之一匹配。
答案 9 :(得分:0)
实际上我发现@Dan McGrath的答案在这里工作是对他的答案的重写:
private void query() {
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("STATUS")
.whereIn("status", Arrays.asList("open", "upcoming")) // you can add up to 10 different values like : Arrays.asList("open", "upcoming", "Pending", "In Progress", ...)
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
for (DocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
// I assume you have a model class called MyStatus
MyStatus status= documentSnapshot.toObject(MyStatus.class);
if (status!= null) {
//do somthing...!
}
}
}
});
}