Database 如何使用逻辑或云中Firestore执行复合查询?

Database 如何使用逻辑或云中Firestore执行复合查询?,database,firebase,google-cloud-platform,google-cloud-firestore,Database,Firebase,Google Cloud Platform,Google Cloud Firestore,发件人: 还可以链接多个where()方法以创建更具体的查询(逻辑AND) 如何执行或查询? 例如: 将状态字段为打开或即将到来 请提供所有不支持字段status==open或createdAt或的文档,因为服务器很难对其进行扩展(需要将状态保持为重复数据消除)。解决方法是在客户端上发出两个查询(每个条件一个)和重复数据消除 编辑(2019年11月): Cloud Firestore现在支持IN查询,这是一种有限类型的或查询 对于上面的示例,您可以执行以下操作: // Get all docu

发件人:

还可以链接多个where()方法以创建更具体的查询(逻辑AND)

如何执行
查询?
例如:

  • 状态
    字段为
    打开
    即将到来

  • 请提供所有不支持字段
    status==open
    createdAt
    的文档,因为服务器很难对其进行扩展(需要将状态保持为重复数据消除)。解决方法是在客户端上发出两个查询(每个条件一个)和重复数据消除


    编辑(2019年11月):

    Cloud Firestore现在支持
    IN
    查询,这是一种有限类型的
    查询

    对于上面的示例,您可以执行以下操作:

    // Get all documents in 'foo' where status is open or upcmoming
    db.collection('foo').where('status','in',['open','upcoming']).get()
    

    但是,仍然无法执行涉及多个字段的常规
    条件。

    您可以使用rxjs合并运算符绑定两个观察值。 这里有一个例子

    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());
    }
    

    我希望这能帮助你,来自智利的问候

    建议也给状态赋值。
    例如。

    您可以通过
    ref.where('statusValue','p>进行查询,我没有“status”字段,而是与状态相关的字段,根据请求将它们更新为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)...
    

    希望有帮助。

    我们刚才也遇到了同样的问题,幸运的是我们唯一可能的值是A,B,C,D(4),所以我们必须查询A | | B,A | | C,A | | B | C,D等


    就像几个月前一样,firebase支持一个新的查询
    数组包含的内容
    ,因此我们要做的是创建一个数组,并对数组中的OR值进行预处理

    if (a) {
    array addObject:@"a"
    }
    if (b) {
    array addObject:@"b"
    }
    if (a||b) {
    array addObject:@"a||b"
    }
    etc
    
    我们对所有
    4!
    值或任何组合都这样做

    然后我们可以简单地检查查询
    [文档数组内容:@“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 | | C”)


    注意:如果您有几个可能的值要比较或比较,那么这只是一种合理的方法

    有关的详细信息,因为firebase docs对它是新的,或者不支持它

    但如果需要,可以在代码中实现

    例如:如果我想查询(尺寸等于Xl或XXL:且性别为男性)的产品

    productsCollectionRef
    //1*首先获取查询firestore在哪里可以处理它
    .whereEqualTo(“性别”、“男性”)
    .addSnapshotListener((queryDocumentSnapshots,e)->{
    if(queryDocumentSnapshots==null)
    返回;
    List productList=new ArrayList();
    对于(DocumentSnapshot快照:queryDocumentSnapshots.getDocuments()){
    Product Product=snapshot.toObject(Product.class);
    //2*然后检查您的查询或条件,因为firestore仅提供支持和条件
    if(product.getSize()等于(“XL”)| product.getSize()等于(“XXL”))
    productList.add(产品);
    }
    liveData.setValue(productList);
    });
    
    使用,Firestore支持“在同一字段上使用逻辑最多10个相等子句”

    (1)的一个可能解决方案是:

    documents.where('status','in',['open','comming']);
    

    有关颤振省道语言,请参见以下内容:

    db.collection("projects").where("status", whereIn: ["public", "unlisted", "secret"]);
    

    这并不能解决所有情况,但对于“enum”字段,您可以模拟“OR”查询,方法是为每个enum值创建一个单独的布尔字段,然后为每个不属于“OR”子句的值添加一个
    where(“enum_)”,“==”,false)

    例如,考虑您的第一个期望查询:

  • 给我所有字段状态为“打开”或“即将打开”的文档
  • 您可以通过将
    status:string
    字段拆分为多个布尔字段来完成此操作,每个枚举值对应一个布尔字段:

    status_open: bool
    status_upcoming: bool
    status_suspended: bool
    status_closed: bool
    
    要执行“何处状态为打开或即将到来”查询,请执行以下操作:

    where("status_suspended", "==", false).where("status_closed", "==", false)
    
    这是如何工作的?因为它是一个枚举,您知道其中一个值必须赋值为
    true
    。因此,如果您可以确定所有其他值与给定的条目不匹配,那么通过推断,它必须与您最初查找的值之一匹配

    另见
    /
    不在
    /
    数组包含在
    中:


    !=

    事实上,我发现@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...!
                                }
                            }
                        }
                    });
    
        }
    
    private void query(){
    FirebaseFirestore db=FirebaseFirestore.getInstance();
    db.收款(“状态”)
    。其中(“status”,Arrays.asList(“open”,“uncoming”)//您最多可以添加10个不同的值,例如:Arrays.asList(“open”,“uncoming”,“Pending”,“In Progress”,“In Progress…”)
    .addSnapshotListener(新的EventListener(){
    @凌驾
    public void OneEvent(@Nullable QuerySnapshot queryDocumentSnapshots,@Nullable FirebaseFirestoreException e){
    对于(DocumentSnapshot DocumentSnapshot:queryDocumentSnapshots){
    //我假设您有一个名为MyStatus的模型类
    MyStatus status=documentSnapshot.toObject(MyStatus.class);
    如果(状态!=null){
    //做
    
    status_open: bool
    status_upcoming: bool
    status_suspended: bool
    status_closed: bool
    
    where("status_suspended", "==", false).where("status_closed", "==", false)
    
     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...!
                                }
                            }
                        }
                    });
    
        }