问答中心分类: FIREBASE基于 Firebase 中多个 where 子句的查询
0
匿名用户 提问 5小时 前
{
  "movies": {
    "movie1": {
      "genre": "comedy",
      "name": "As good as it gets",
      "lead": "Jack Nicholson"
    },
    "movie2": {
      "genre": "Horror",
      "name": "The Shining",
      "lead": "Jack Nicholson"
    },
    "movie3": {
      "genre": "comedy",
      "name": "The Mask",
      "lead": "Jim Carrey"
    }
  }
}

我是 Firebase 新手。如何从上面的数据中检索结果在哪里genre = 'comedy'lead = 'Jack Nicholson'?
我有什么选择?

7 Answers
0
David East 回答 5小时 前

我编写了一个个人库,允许您按多个值排序,所有排序都在服务器上完成。
认识查询库!
Querybase 接受 Firebase 数据库参考和您希望索引的字段数组。当您创建新记录时,它将自动处理允许多次查询的键的生成。需要注意的是,它只支持直接等价(不小于或大于)。

const databaseRef = firebase.database().ref().child('people');
const querybaseRef = querybase.ref(databaseRef, ['name', 'age', 'location']);

// Automatically handles composite keys
querybaseRef.push({ 
  name: 'David',
  age: 27,
  location: 'SF'
});

// Find records by multiple fields
// returns a Firebase Database ref
const queriedDbRef = querybaseRef
 .where({
   name: 'David',
   age: 27
 });

// Listen for realtime updates
queriedDbRef.on('value', snap => console.log(snap));
Levi Fuller 回复 5小时 前

您的库有任何可用的 TypeScript 定义吗?

David East 回复 5小时 前

是用TS写的!所以只需导入:)

Levi Fuller 回复 5小时 前

即使缓冲区类型正确解析缓冲区,我也收到缓冲区未定义错误。我确实必须修改getKey()参考自this.getKey = () => this.ref().getKey();this.getKey = () => this.ref().key();假设是因为不同版本的firebase,但我认为这不会影响它。

Levi Fuller 回复 5小时 前

在我投入过多之前,Querybase 是否支持以下内容:let ref = this.firebase.child('test/checkpoints'); // example Checkpoint = {name: "Building an app", tags: {{tier: "1", "name": "apps"}, {tier: "2", "name": "angular2"}}} let querybase = new Querybase(ref, ['tags']); let queryRef = querybase.where({tags: {tier: "1", name: "apps"}}); queryRef.on('value', snap => console.log(snap));

David East 回复 5小时 前

这仅与 Firebase 3.0 兼容。我可能需要为浏览器用户添加一个 Buffer 环境声明。

Levi Fuller 回复 5小时 前

刚刚意识到我为 Firebase 输入的内容很旧。需要找到一些较新的。编辑:我猜你的图书馆也使用相同的 Firebase 类型2.4.1

David East 回复 5小时 前

@LeviFuller 是的,因为我只依赖 API 没有太大变化的数据库参考。我在本地修改了小改动。正式版还没有发货。不过,我们在 AngulaFire2 库中确实有非官方的类型。

Levi Fuller 回复 5小时 前

让我们在聊天中继续讨论.

Denis Truffaut 回复 5小时 前

@David East – 我正在使用 Polymer,处理 AND 查询的最佳方法是什么(有或没有你的 QueryBase)?

LOG_TAG 回复 5小时 前

@DavidEast 所有这些过滤器黑客都适用于 Android firbase 客户端?根据位置星级、评级等过滤酒店搜索过滤器??

Nicholas 回复 5小时 前

@DavidEast 我尝试在打字稿中导入,但它不起作用。 node_modules 中仅存在 .js 文件。如何使用它?

Ced 回复 5小时 前

你知道他们为什么让数据库如此严格吗?

mding5692 回复 5小时 前

执行 IOS Swift/Android 版本的任何选项

Rizwan Jamal 回复 5小时 前

嗨大卫,你能告诉我如何在使用 querybaseRef.push(payload) 时向对象添加推送键。就像我们可以在 firebase db 中正常使用 ref.push().key

Rizwan Jamal 回复 5小时 前

嗨大卫,在 npm install querybase –save 之后,当我像 import * as querybase from ‘querybase’ 一样导入它时;得到 typeErrors ‘找不到模块’,我发现在 node_modules 下所有扩展名为 .js 的文件为什么模块不包含 .ts 文件?

Fadi 回复 5小时 前

嗨,大卫,我们可以过滤嵌套字段吗?

Snake 回复 5小时 前

大卫,有任何 android/Java 等价物吗?

Filippos 回复 5小时 前

我们可以在 Android 项目上使用 QueryBase 吗?

Supertecnoboff 回复 5小时 前

这样做的问题是它需要云代码…..有时在 Firebase 上可能会很慢。

exequielc 回复 5小时 前

有没有类似 Dart 的库?

kushal Baldev 回复 5小时 前

我刚刚通过 npm install querybase –save 安装,但对下一步如何使查询库可用感到困惑?该文档没有提供明确的指导方针

0
Andrew Lam 回答 5小时 前
var ref = new Firebase('https://your.firebaseio.com/');

Query query = ref.orderByChild('genre').equalTo('comedy');
query.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot movieSnapshot : dataSnapshot.getChildren()) {
            Movie movie = dataSnapshot.getValue(Movie.class);
            if (movie.getLead().equals('Jack Nicholson')) {
                console.log(movieSnapshot.getKey());
            }
        }
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
});
Parag Kadam 回复 5小时 前

DataSnapshot 对象上没有 getLead() 方法。

Kim G Pham 回复 5小时 前

他将其转换为 Movie 对象并假设有一个 getLead() 方法。

Nuwan Withanage 回复 5小时 前

非常感谢。它的工作原理是更多的 where 子句

Kamlesh 回复 5小时 前

我正在使用火库。在这种情况下,我们如何使用 where 条件 – 获取“(senderid == loggedinuserid and receiverid == 10)或(senderid == 10 and receiverid == loggedinuserid)”的所有聊天对话?请建议。谢谢。

0
Tidder Jail 回答 5小时 前

弗兰克的回答很好,但 Firestore 介绍了array-contains最近,这使得执行 AND 查询变得更加容易。
您可以创建一个filters字段以添加您的过滤器。您可以根据需要添加任意数量的值。例如过滤喜剧杰克尼科尔森你可以添加值comedy_Jack Nicholson但如果你也想通过喜剧2014你可以添加值comedy_2014无需创建更多字段。

{
  "movies": {
    "movie1": {
      "genre": "comedy",
      "name": "As good as it gets",
      "lead": "Jack Nicholson",
      "year": 2014,
      "filters": [
        "comedy_Jack Nicholson",
        "comedy_2014"
      ]
    }
  }
}
0
mayur 回答 5小时 前

Firebase 不允许使用多个条件进行查询。但是,我确实找到了解决方法:
我们需要从数据库中下载初始过滤数据并将其存储在数组列表中。

Query query = databaseReference.orderByChild("genre").equalTo("comedy");
                databaseReference.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                        ArrayList<Movie> movies = new ArrayList<>();
                        for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
                            String lead = dataSnapshot1.child("lead").getValue(String.class);
                            String genre = dataSnapshot1.child("genre").getValue(String.class);

                            movie = new Movie(lead, genre);

                            movies.add(movie);

                        }

                        filterResults(movies, "Jack Nicholson");

                        }

                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });

一旦我们从数据库中获得初始过滤数据,我们需要在后端进行进一步的过滤。

public void filterResults(final List<Movie> list,  final String genre) {
        List<Movie> movies = new ArrayList<>();
        movies = list.stream().filter(o -> o.getLead().equals(genre)).collect(Collectors.toList());
        System.out.println(movies);

        employees.forEach(movie -> System.out.println(movie.getFirstName()));
    }
0
Sage 回答 5小时 前

对于 Cloud Firestore
https://firebase.google.com/docs/firestore/query-data/queries#compound_queries
复合查询 您可以链接多个相等运算符(== 或数组包含)方法来创建更具体的查询(逻辑 AND)。但是,您必须创建一个复合索引来组合等式运算符和不等式运算符,<, <=, >, and !=.

citiesRef.where('state', '==', 'CO').where('name', '==', 'Denver');
citiesRef.where('state', '==', 'CA').where('population', '<', 1000000);

您可以执行范围(<, <=, >, >=)或不等于(!=)仅在单个字段上进行比较,并且您最多可以在复合查询中包含一个 array-contains 或 array-contains-any 子句:

John Miller 回复 5小时 前

这是正确的,尽管将代码放在代码块中会更好。