Sử dụng API truy vấn của Firebase , bạn có thể muốn thử điều này:
// !!! THIS WILL NOT WORK !!!
ref
.orderBy('genre')
.startAt('comedy').endAt('comedy')
.orderBy('lead') // !!! THIS LINE WILL RAISE AN ERROR !!!
.startAt('Jack Nicholson').endAt('Jack Nicholson')
.on('value', function(snapshot) {
console.log(snapshot.val());
});
Nhưng như @RobDiMarco từ Firebase nói trong các bình luận:
nhiều orderBy()
cuộc gọi sẽ gây ra lỗi
Vì vậy, mã của tôi ở trên sẽ không hoạt động .
Tôi biết ba cách tiếp cận sẽ làm việc.
1. lọc hầu hết trên máy chủ, làm phần còn lại trên máy khách
Những gì bạn có thể làm là thực thi một cái orderBy().startAt()./endAt()
trên máy chủ, kéo xuống dữ liệu còn lại và lọc theo mã JavaScript trên máy khách của bạn.
ref
.orderBy('genre')
.equalTo('comedy')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
if (movie.lead == 'Jack Nicholson') {
console.log(movie);
}
});
2. thêm thuộc tính kết hợp các giá trị mà bạn muốn lọc
Nếu điều đó không đủ tốt, bạn nên xem xét sửa đổi / mở rộng dữ liệu của mình để cho phép trường hợp sử dụng của bạn. Ví dụ: bạn có thể nhồi thể loại + dẫn vào một thuộc tính mà bạn chỉ sử dụng cho bộ lọc này.
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_lead": "comedy_Jack Nicholson"
},...
Về cơ bản, bạn đang xây dựng chỉ mục nhiều cột của riêng mình và có thể truy vấn nó bằng:
ref
.orderBy('genre_lead')
.equalTo('comedy_Jack Nicholson')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
David East đã viết một thư viện có tên QueryBase giúp tạo các thuộc tính như vậy .
Bạn thậm chí có thể thực hiện các truy vấn tương đối / phạm vi, giả sử rằng bạn muốn cho phép truy vấn phim theo thể loại và năm. Bạn sẽ sử dụng cấu trúc dữ liệu này:
"movie1": {
"genre": "comedy",
"name": "As good as it gets",
"lead": "Jack Nicholson",
"genre_year": "comedy_1997"
},...
Và sau đó truy vấn các phim hài của thập niên 90 với:
ref
.orderBy('genre_year')
.startAt('comedy_1990')
.endAt('comedy_2000')
.on('child_added', function(snapshot) {
var movie = snapshot.val();
console.log(movie);
});
Nếu bạn cần lọc nhiều hơn chỉ trong năm, hãy đảm bảo thêm các phần ngày khác theo thứ tự giảm dần, ví dụ "comedy_1997-12-25"
. Bằng cách này, thứ tự từ điển mà Firebase thực hiện trên các giá trị chuỗi sẽ giống như thứ tự thời gian.
Sự kết hợp các giá trị này trong một thuộc tính có thể hoạt động với nhiều hơn hai giá trị, nhưng bạn chỉ có thể thực hiện một bộ lọc phạm vi trên giá trị cuối cùng trong thuộc tính tổng hợp.
Một biến thể rất đặc biệt của điều này được thư viện GeoFire thực hiện cho Firebase . Thư viện này kết hợp vĩ độ và kinh độ của một vị trí vào cái gọi là Geohash , sau đó có thể được sử dụng để thực hiện các truy vấn phạm vi thời gian thực trên Firebase.
3. tạo một chỉ mục tùy chỉnh theo chương trình
Tuy nhiên, một cách khác là làm tất cả những gì chúng ta đã làm trước khi API truy vấn mới này được thêm vào: tạo một chỉ mục trong một nút khác:
"movies"
// the same structure you have today
"by_genre"
"comedy"
"by_lead"
"Jack Nicholson"
"movie1"
"Jim Carrey"
"movie3"
"Horror"
"by_lead"
"Jack Nicholson"
"movie2"
Có lẽ có nhiều cách tiếp cận hơn. Ví dụ: câu trả lời này làm nổi bật một chỉ mục tùy chỉnh hình cây thay thế: https://stackoverflow.com/a 432105063
orderBy()
cuộc gọi sẽ xuất hiện lỗi, vì các máy khách hiện đang cho kết quả không mong muốn. Có thể nó tình cờ hoạt động trong thử nghiệm của bạn, nhưng không được xây dựng để hoạt động chung chung (mặc dù chúng tôi muốn thêm nó!).