O Cloud Firestore oferece funcionalidades de consulta poderosas para especificar quais documentos você deseja recuperar de uma coleção ou grupo de coleções. Essas consultas também podem ser usadas com get()
ou addSnapshotListener()
, conforme descrito em Obter dados e obter atualizações em tempo real .
Dados de exemplo
Para começar, escreva alguns dados sobre cidades para que possamos ver diferentes maneiras de lê-los:
Web modular API
import { collection, doc, setDoc } from "firebase/firestore"; const citiesRef = collection(db, "cities"); await setDoc(doc(citiesRef, "SF"), { name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860000, regions: ["west_coast", "norcal"] }); await setDoc(doc(citiesRef, "LA"), { name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3900000, regions: ["west_coast", "socal"] }); await setDoc(doc(citiesRef, "DC"), { name: "Washington, D.C.", state: null, country: "USA", capital: true, population: 680000, regions: ["east_coast"] }); await setDoc(doc(citiesRef, "TOK"), { name: "Tokyo", state: null, country: "Japan", capital: true, population: 9000000, regions: ["kanto", "honshu"] }); await setDoc(doc(citiesRef, "BJ"), { name: "Beijing", state: null, country: "China", capital: true, population: 21500000, regions: ["jingjinji", "hebei"] });
Web namespaced API
var citiesRef = db.collection("cities"); citiesRef.doc("SF").set({ name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860000, regions: ["west_coast", "norcal"] }); citiesRef.doc("LA").set({ name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3900000, regions: ["west_coast", "socal"] }); citiesRef.doc("DC").set({ name: "Washington, D.C.", state: null, country: "USA", capital: true, population: 680000, regions: ["east_coast"] }); citiesRef.doc("TOK").set({ name: "Tokyo", state: null, country: "Japan", capital: true, population: 9000000, regions: ["kanto", "honshu"] }); citiesRef.doc("BJ").set({ name: "Beijing", state: null, country: "China", capital: true, population: 21500000, regions: ["jingjinji", "hebei"] });
Rápido
let citiesRef = db.collection("cities") citiesRef.document("SF").setData([ "name": "San Francisco", "state": "CA", "country": "USA", "capital": false, "population": 860000, "regions": ["west_coast", "norcal"] ]) citiesRef.document("LA").setData([ "name": "Los Angeles", "state": "CA", "country": "USA", "capital": false, "population": 3900000, "regions": ["west_coast", "socal"] ]) citiesRef.document("DC").setData([ "name": "Washington D.C.", "country": "USA", "capital": true, "population": 680000, "regions": ["east_coast"] ]) citiesRef.document("TOK").setData([ "name": "Tokyo", "country": "Japan", "capital": true, "population": 9000000, "regions": ["kanto", "honshu"] ]) citiesRef.document("BJ").setData([ "name": "Beijing", "country": "China", "capital": true, "population": 21500000, "regions": ["jingjinji", "hebei"] ])
Objetivo-C
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [[citiesRef documentWithPath:@"SF"] setData:@{ @"name": @"San Francisco", @"state": @"CA", @"country": @"USA", @"capital": @(NO), @"population": @860000, @"regions": @[@"west_coast", @"norcal"] }]; [[citiesRef documentWithPath:@"LA"] setData:@{ @"name": @"Los Angeles", @"state": @"CA", @"country": @"USA", @"capital": @(NO), @"population": @3900000, @"regions": @[@"west_coast", @"socal"] }]; [[citiesRef documentWithPath:@"DC"] setData:@{ @"name": @"Washington D.C.", @"country": @"USA", @"capital": @(YES), @"population": @680000, @"regions": @[@"east_coast"] }]; [[citiesRef documentWithPath:@"TOK"] setData:@{ @"name": @"Tokyo", @"country": @"Japan", @"capital": @(YES), @"population": @9000000, @"regions": @[@"kanto", @"honshu"] }]; [[citiesRef documentWithPath:@"BJ"] setData:@{ @"name": @"Beijing", @"country": @"China", @"capital": @(YES), @"population": @21500000, @"regions": @[@"jingjinji", @"hebei"] }];
Kotlin+KTX
val cities = db.collection("cities") val data1 = hashMapOf( "name" to "San Francisco", "state" to "CA", "country" to "USA", "capital" to false, "population" to 860000, "regions" to listOf("west_coast", "norcal"), ) cities.document("SF").set(data1) val data2 = hashMapOf( "name" to "Los Angeles", "state" to "CA", "country" to "USA", "capital" to false, "population" to 3900000, "regions" to listOf("west_coast", "socal"), ) cities.document("LA").set(data2) val data3 = hashMapOf( "name" to "Washington D.C.", "state" to null, "country" to "USA", "capital" to true, "population" to 680000, "regions" to listOf("east_coast"), ) cities.document("DC").set(data3) val data4 = hashMapOf( "name" to "Tokyo", "state" to null, "country" to "Japan", "capital" to true, "population" to 9000000, "regions" to listOf("kanto", "honshu"), ) cities.document("TOK").set(data4) val data5 = hashMapOf( "name" to "Beijing", "state" to null, "country" to "China", "capital" to true, "population" to 21500000, "regions" to listOf("jingjinji", "hebei"), ) cities.document("BJ").set(data5)
Java
CollectionReference cities = db.collection("cities"); Map<String, Object> data1 = new HashMap<>(); data1.put("name", "San Francisco"); data1.put("state", "CA"); data1.put("country", "USA"); data1.put("capital", false); data1.put("population", 860000); data1.put("regions", Arrays.asList("west_coast", "norcal")); cities.document("SF").set(data1); Map<String, Object> data2 = new HashMap<>(); data2.put("name", "Los Angeles"); data2.put("state", "CA"); data2.put("country", "USA"); data2.put("capital", false); data2.put("population", 3900000); data2.put("regions", Arrays.asList("west_coast", "socal")); cities.document("LA").set(data2); Map<String, Object> data3 = new HashMap<>(); data3.put("name", "Washington D.C."); data3.put("state", null); data3.put("country", "USA"); data3.put("capital", true); data3.put("population", 680000); data3.put("regions", Arrays.asList("east_coast")); cities.document("DC").set(data3); Map<String, Object> data4 = new HashMap<>(); data4.put("name", "Tokyo"); data4.put("state", null); data4.put("country", "Japan"); data4.put("capital", true); data4.put("population", 9000000); data4.put("regions", Arrays.asList("kanto", "honshu")); cities.document("TOK").set(data4); Map<String, Object> data5 = new HashMap<>(); data5.put("name", "Beijing"); data5.put("state", null); data5.put("country", "China"); data5.put("capital", true); data5.put("population", 21500000); data5.put("regions", Arrays.asList("jingjinji", "hebei")); cities.document("BJ").set(data5);
Dart
final cities = db.collection("cities"); final data1 = <String, dynamic>{ "name": "San Francisco", "state": "CA", "country": "USA", "capital": false, "population": 860000, "regions": ["west_coast", "norcal"] }; cities.doc("SF").set(data1); final data2 = <String, dynamic>{ "name": "Los Angeles", "state": "CA", "country": "USA", "capital": false, "population": 3900000, "regions": ["west_coast", "socal"], }; cities.doc("LA").set(data2); final data3 = <String, dynamic>{ "name": "Washington D.C.", "state": null, "country": "USA", "capital": true, "population": 680000, "regions": ["east_coast"] }; cities.doc("DC").set(data3); final data4 = <String, dynamic>{ "name": "Tokyo", "state": null, "country": "Japan", "capital": true, "population": 9000000, "regions": ["kanto", "honshu"] }; cities.doc("TOK").set(data4); final data5 = <String, dynamic>{ "name": "Beijing", "state": null, "country": "China", "capital": true, "population": 21500000, "regions": ["jingjinji", "hebei"], }; cities.doc("BJ").set(data5);
Java
Pitão
class City: def __init__(self, name, state, country, capital=False, population=0, regions=[]): self.name = name self.state = state self.country = country self.capital = capital self.population = population self.regions = regions @staticmethod def from_dict(source): # ... def to_dict(self): # ... def __repr__(self): return f"City(\ name={self.name}, \ country={self.country}, \ population={self.population}, \ capital={self.capital}, \ regions={self.regions}\ )"
cities_ref = db.collection("cities") cities_ref.document("BJ").set( City("Beijing", None, "China", True, 21500000, ["hebei"]).to_dict() ) cities_ref.document("SF").set( City( "San Francisco", "CA", "USA", False, 860000, ["west_coast", "norcal"] ).to_dict() ) cities_ref.document("LA").set( City( "Los Angeles", "CA", "USA", False, 3900000, ["west_coast", "socal"] ).to_dict() ) cities_ref.document("DC").set( City("Washington D.C.", None, "USA", True, 680000, ["east_coast"]).to_dict() ) cities_ref.document("TOK").set( City("Tokyo", None, "Japan", True, 9000000, ["kanto", "honshu"]).to_dict() )
Python
class City: def __init__(self, name, state, country, capital=False, population=0, regions=[]): self.name = name self.state = state self.country = country self.capital = capital self.population = population self.regions = regions @staticmethod def from_dict(source): # ... def to_dict(self): # ... def __repr__(self): return f"City(\ name={self.name}, \ country={self.country}, \ population={self.population}, \ capital={self.capital}, \ regions={self.regions}\ )"
cities_ref = db.collection("cities") await cities_ref.document("BJ").set( City("Beijing", None, "China", True, 21500000, ["hebei"]).to_dict() ) await cities_ref.document("SF").set( City( "San Francisco", "CA", "USA", False, 860000, ["west_coast", "norcal"] ).to_dict() ) await cities_ref.document("LA").set( City( "Los Angeles", "CA", "USA", False, 3900000, ["west_coast", "socal"] ).to_dict() ) await cities_ref.document("DC").set( City("Washington D.C.", None, "USA", True, 680000, ["east_coast"]).to_dict() ) await cities_ref.document("TOK").set( City("Tokyo", None, "Japan", True, 9000000, ["kanto", "honshu"]).to_dict() )
C++
CollectionReference cities = db->Collection("cities"); cities.Document("SF").Set({ {"name", FieldValue::String("San Francisco")}, {"state", FieldValue::String("CA")}, {"country", FieldValue::String("USA")}, {"capital", FieldValue::Boolean(false)}, {"population", FieldValue::Integer(860000)}, {"regions", FieldValue::Array({FieldValue::String("west_coast"), FieldValue::String("norcal")})}, }); cities.Document("LA").Set({ {"name", FieldValue::String("Los Angeles")}, {"state", FieldValue::String("CA")}, {"country", FieldValue::String("USA")}, {"capital", FieldValue::Boolean(false)}, {"population", FieldValue::Integer(3900000)}, {"regions", FieldValue::Array({FieldValue::String("west_coast"), FieldValue::String("socal")})}, }); cities.Document("DC").Set({ {"name", FieldValue::String("Washington D.C.")}, {"state", FieldValue::Null()}, {"country", FieldValue::String("USA")}, {"capital", FieldValue::Boolean(true)}, {"population", FieldValue::Integer(680000)}, {"regions", FieldValue::Array({FieldValue::String("east_coast")})}, }); cities.Document("TOK").Set({ {"name", FieldValue::String("Tokyo")}, {"state", FieldValue::Null()}, {"country", FieldValue::String("Japan")}, {"capital", FieldValue::Boolean(true)}, {"population", FieldValue::Integer(9000000)}, {"regions", FieldValue::Array({FieldValue::String("kanto"), FieldValue::String("honshu")})}, }); cities.Document("BJ").Set({ {"name", FieldValue::String("Beijing")}, {"state", FieldValue::Null()}, {"country", FieldValue::String("China")}, {"capital", FieldValue::Boolean(true)}, {"population", FieldValue::Integer(21500000)}, {"regions", FieldValue::Array({FieldValue::String("jingjinji"), FieldValue::String("hebei")})}, });
Node.js
Ir
PHP
Unidade
CollectionReference citiesRef = db.Collection("cities"); citiesRef.Document("SF").SetAsync(new Dictionary<string, object>(){ { "Name", "San Francisco" }, { "State", "CA" }, { "Country", "USA" }, { "Capital", false }, { "Population", 860000 }, { "Regions", new ArrayList{"west_coast", "norcal"} } }); citiesRef.Document("LA").SetAsync(new Dictionary<string, object>(){ { "Name", "Los Angeles" }, { "State", "CA" }, { "Country", "USA" }, { "Capital", false }, { "Population", 3900000 }, { "Regions", new ArrayList{"west_coast", "socal"} } }); citiesRef.Document("DC").SetAsync(new Dictionary<string, object>(){ { "Name", "Washington D.C." }, { "State", null }, { "Country", "USA" }, { "Capital", true }, { "Population", 680000 }, { "Regions", new ArrayList{"east_coast"} } }); citiesRef.Document("TOK").SetAsync(new Dictionary<string, object>(){ { "Name", "Tokyo" }, { "State", null }, { "Country", "Japan" }, { "Capital", true }, { "Population", 9000000 }, { "Regions", new ArrayList{"kanto", "honshu"} } }); citiesRef.Document("BJ").SetAsync(new Dictionary<string, object>(){ { "Name", "Beijing" }, { "State", null }, { "Country", "China" }, { "Capital", true }, { "Population", 21500000 }, { "Regions", new ArrayList{"jingjinji", "hebei"} } });
C#
Rubi
Consultas simples
A consulta a seguir retorna todas as cidades com estado CA
:
Web modular API
// Create a reference to the cities collection import { collection, query, where } from "firebase/firestore"; const citiesRef = collection(db, "cities"); // Create a query against the collection. const q = query(citiesRef, where("state", "==", "CA"));
Web namespaced API
// Create a reference to the cities collection var citiesRef = db.collection("cities"); // Create a query against the collection. var query = citiesRef.where("state", "==", "CA");
Rápido
// Create a reference to the cities collection let citiesRef = db.collection("cities") // Create a query against the collection. let query = citiesRef.whereField("state", isEqualTo: "CA")
Objetivo-C
// Create a reference to the cities collection FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; // Create a query against the collection. FIRQuery *query = [citiesRef queryWhereField:@"state" isEqualTo:@"CA"];
Kotlin+KTX
// Create a reference to the cities collection val citiesRef = db.collection("cities") // Create a query against the collection. val query = citiesRef.whereEqualTo("state", "CA")
Java
// Create a reference to the cities collection CollectionReference citiesRef = db.collection("cities"); // Create a query against the collection. Query query = citiesRef.whereEqualTo("state", "CA");
Dart
// Create a reference to the cities collection final citiesRef = db.collection("cities"); // Create a query against the collection. final query = citiesRef.where("state", isEqualTo: "CA");
Java
Pitão
Python
C++
CollectionReference cities_ref = db->Collection("cities"); // Create a query against the collection. Query query_ca = cities_ref.WhereEqualTo("state", FieldValue::String("CA"));
Node.js
Ir
PHP
Unidade
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereEqualTo("State", "CA"); query.GetSnapshotAsync().ContinueWithOnMainThread((querySnapshotTask) => { foreach (DocumentSnapshot documentSnapshot in querySnapshotTask.Result.Documents) { Debug.Log(String.Format("Document {0} returned by query State=CA", documentSnapshot.Id)); } });
C#
Rubi
A consulta a seguir retorna todas as capitais:
Web modular API
import { collection, query, where } from "firebase/firestore"; const citiesRef = collection(db, "cities"); const q = query(citiesRef, where("capital", "==", true));
Web namespaced API
var citiesRef = db.collection("cities"); var query = citiesRef.where("capital", "==", true);
Rápido
let capitalCities = db.collection("cities").whereField("capital", isEqualTo: true)
Objetivo-C
FIRQuery *capitalCities = [[self.db collectionWithPath:@"cities"] queryWhereField:@"capital" isEqualTo:@YES];
Kotlin+KTX
val capitalCities = db.collection("cities").whereEqualTo("capital", true)
Java
Query capitalCities = db.collection("cities").whereEqualTo("capital", true);
Dart
final capitalcities = db.collection("cities").where("capital", isEqualTo: true);
Java
Pitão
Python
C++
Query capital_cities = db->Collection("cities").WhereEqualTo( "capital", FieldValue::Boolean(true));
Node.js
Ir
PHP
Unidade
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereEqualTo("Capital", true); query.GetSnapshotAsync().ContinueWithOnMainThread((querySnapshotTask) => { foreach (DocumentSnapshot documentSnapshot in querySnapshotTask.Result.Documents) { Debug.Log(String.Format("Document {0} returned by query Capital=true", documentSnapshot.Id)); } });
C#
Rubi
Executar uma consulta
Após criar um objeto de consulta, use a função get()
para recuperar os resultados:
Web modular API
import { collection, query, where, getDocs } from "firebase/firestore"; const q = query(collection(db, "cities"), where("capital", "==", true)); const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots console.log(doc.id, " => ", doc.data()); });
Web namespaced API
db.collection("cities").where("capital", "==", true) .get() .then((querySnapshot) => { querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots console.log(doc.id, " => ", doc.data()); }); }) .catch((error) => { console.log("Error getting documents: ", error); });
Rápido
do { let querySnapshot = try await db.collection("cities").whereField("capital", isEqualTo: true) .getDocuments() for document in querySnapshot.documents { print("\(document.documentID) => \(document.data())") } } catch { print("Error getting documents: \(error)") }
Objetivo-C
[[[self.db collectionWithPath:@"cities"] queryWhereField:@"capital" isEqualTo:@(YES)] getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) { if (error != nil) { NSLog(@"Error getting documents: %@", error); } else { for (FIRDocumentSnapshot *document in snapshot.documents) { NSLog(@"%@ => %@", document.documentID, document.data); } } }];
Kotlin+KTX
db.collection("cities") .whereEqualTo("capital", true) .get() .addOnSuccessListener { documents -> for (document in documents) { Log.d(TAG, "${document.id} => ${document.data}") } } .addOnFailureListener { exception -> Log.w(TAG, "Error getting documents: ", exception) }
Java
db.collection("cities") .whereEqualTo("capital", true) .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { Log.d(TAG, document.getId() + " => " + document.getData()); } } else { Log.d(TAG, "Error getting documents: ", task.getException()); } } });
Dart
db.collection("cities").where("capital", isEqualTo: true).get().then( (querySnapshot) { print("Successfully completed"); for (var docSnapshot in querySnapshot.docs) { print('${docSnapshot.id} => ${docSnapshot.data()}'); } }, onError: (e) => print("Error completing: $e"), );
Java
Pitão
Python
C++
db->Collection("cities") .WhereEqualTo("capital", FieldValue::Boolean(true)) .Get() .OnCompletion([](const Future<QuerySnapshot>& future) { if (future.error() == Error::kErrorOk) { for (const DocumentSnapshot& document : future.result()->documents()) { std::cout << document << std::endl; } } else { std::cout << "Error getting documents: " << future.error_message() << std::endl; } });
Node.js
Ir
PHP
PHP
Para obter mais informações sobre como instalar e criar um cliente Cloud Firestore, consulte Bibliotecas de cliente Cloud Firestore .
Unidade
Query capitalQuery = db.Collection("cities").WhereEqualTo("Capital", true); capitalQuery.GetSnapshotAsync().ContinueWithOnMainThread(task => { QuerySnapshot capitalQuerySnapshot = task.Result; foreach (DocumentSnapshot documentSnapshot in capitalQuerySnapshot.Documents) { Debug.Log(String.Format("Document data for {0} document:", documentSnapshot.Id)); Dictionary<string, object> city = documentSnapshot.ToDictionary(); foreach (KeyValuePair<string, object> pair in city) { Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value)); } // Newline to separate entries Debug.Log(""); }; });
C#
Rubi
Consulte Obter dados para obter mais informações sobre como recuperar resultados de consulta. Você também pode adicionar um ouvinte a uma consulta para obter os resultados atuais e ouvir atualizações futuras.
Operadores de consulta
O método where()
usa três parâmetros: um campo para filtrar, um operador de comparação e um valor. O Cloud Firestore oferece suporte aos seguintes operadores de comparação:
-
<
menos que -
<=
menor ou igual a -
==
igual a -
>
maior que -
>=
maior ou igual a -
!=
diferente de -
array-contains
-
array-contains-any
-
in
-
not-in
Por exemplo:
Web modular API
const stateQuery = query(citiesRef, where("state", "==", "CA")); const populationQuery = query(citiesRef, where("population", "<", 100000)); const nameQuery = query(citiesRef, where("name", ">=", "San Francisco"));
Web namespaced API
const stateQuery = citiesRef.where("state", "==", "CA"); const populationQuery = citiesRef.where("population", "<", 100000); const nameQuery = citiesRef.where("name", ">=", "San Francisco");
Rápido
let stateQuery = citiesRef.whereField("state", isEqualTo: "CA") let populationQuery = citiesRef.whereField("population", isLessThan: 100000) let nameQuery = citiesRef.whereField("name", isGreaterThanOrEqualTo: "San Francisco")
Objetivo-C
FIRQuery *stateQuery = [citiesRef queryWhereField:@"state" isEqualTo:@"CA"]; FIRQuery *populationQuery = [citiesRef queryWhereField:@"population" isLessThan:@100000]; FIRQuery *nameQuery = [citiesRef queryWhereField:@"name" isGreaterThanOrEqualTo:@"San Francisco"];
Kotlin+KTX
val stateQuery = citiesRef.whereEqualTo("state", "CA") val populationQuery = citiesRef.whereLessThan("population", 100000) val nameQuery = citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco")
Java
Query stateQuery = citiesRef.whereEqualTo("state", "CA"); Query populationQuery = citiesRef.whereLessThan("population", 100000); Query nameQuery = citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco");
Dart
final citiesRef = db.collection("cities"); final stateQuery = citiesRef.where("state", isEqualTo: "CA"); final populationQuery = citiesRef.where("population", isLessThan: 100000); final nameQuery = citiesRef.where("name", isEqualTo: "San Francisco");
Java
Pitão
Python
C++
cities_ref.WhereEqualTo("state", FieldValue::String("CA")); cities_ref.WhereLessThan("population", FieldValue::Integer(100000)); cities_ref.WhereGreaterThanOrEqualTo("name", FieldValue::String("San Francisco"));
Node.js
Ir
PHP
Unidade
Query stateQuery = citiesRef.WhereEqualTo("State", "CA"); Query populationQuery = citiesRef.WhereGreaterThan("Population", 1000000); Query nameQuery = citiesRef.WhereGreaterThanOrEqualTo("Name", "San Francisco");
C#
Rubi
Diferente ( !=
)
Use o operador diferente ( !=
) para retornar documentos onde o campo fornecido existe e não corresponde ao valor de comparação. Por exemplo:
Web modular API
const notCapitalQuery = query(citiesRef, where("capital", "!=", false));
Web namespaced API
citiesRef.where("capital", "!=", false);
Rápido
let notEqualQuery = citiesRef.whereField("capital", isNotEqualTo: false)
Objetivo-C
query = [citiesRef queryWhereField:@"capital" isNotEqualTo:@NO];
Kotlin+KTX
val notCapitalQuery = citiesRef.whereNotEqualTo("capital", false)
Java
Query notCapitalQuery = citiesRef.whereNotEqualTo("capital", false);
Dart
final citiesRef = db.collection("cities"); final notCapitals = citiesRef.where("capital", isNotEqualTo: true);
Java
Pitão
// Snippet not yet available
C++
cities_ref.WhereNotEqualTo("capital", FieldValue::Boolean(false));
Node.js
Ir
// Snippet not yet available
PHP
Unidade
Query query = citiesRef.WhereNotEqualTo("capital", false); Query query = citiesRef.WhereNotEqualTo("capital", false);
C#
// Snippet not yet available
Rubi
Esta consulta retorna todos os documentos city
onde existe o campo capital
com um valor diferente de false
ou null
. Isso inclui documentos city
onde o valor do campo capital
é igual true
ou qualquer valor não booleano além de null
.
Esta consulta não retorna documentos city
onde o campo capital
não existe. Consultas diferentes ( !=
) e not-in
excluem documentos onde o campo fornecido não existe .
Um campo existe quando é definido com qualquer valor, incluindo uma string vazia ( ""
), null
e NaN
(não um número). Observe que os valores de campo null
não correspondem às cláusulas !=
, porque x != null
é avaliado como undefined
.
Limitações
Observe as seguintes limitações para consultas !=
:
- Somente documentos onde existe o campo fornecido podem corresponder à consulta.
- Você não pode combinar
not-in
e!=
em uma consulta composta. - Em uma consulta composta, as comparações de intervalo (
<
,<=
,>
,>=
) e não iguais (!=
,not-in
) devem ser filtradas no mesmo campo.
Associação à matriz
Você pode usar o operador array-contains
para filtrar com base nos valores do array. Por exemplo:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where("regions", "array-contains", "west_coast"));
Web namespaced API
citiesRef.where("regions", "array-contains", "west_coast");
Rápido
citiesRef .whereField("regions", arrayContains: "west_coast")
Objetivo-C
[citiesRef queryWhereField:@"state" arrayContains:@"west_coast"];
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereArrayContains("regions", "west_coast")
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereArrayContains("regions", "west_coast");
Dart
final citiesRef = db.collection("cities"); final westCoastcities = citiesRef.where("regions", arrayContains: "west_coast");
Java
Pitão
Python
C++
CollectionReference cities_ref = db->Collection("cities"); cities_ref.WhereArrayContains("region", FieldValue::String("west_coast"));
Node.js
Ir
PHP
Unidade
CollectionReference citiesRef = db.Collection("cities"); Query arrayContainsQuery = citiesRef.WhereArrayContains("region", "west_coast");
C#
Rubi
Esta consulta retorna todos os documentos city
onde o campo regions
é uma matriz que contém west_coast
. Se a matriz tiver diversas instâncias do valor consultado, o documento será incluído nos resultados apenas uma vez.
Você pode usar no máximo uma cláusula array-contains
por disjunção ( or
grupo). Você não pode combinar array-contains
com array-contains-any
na mesma disjunção.
in
, not-in
e array-contains-any
Use o operador in
para combinar até 30 cláusulas de igualdade ( ==
) no mesmo campo com um OR
lógico. Uma consulta in
retorna documentos onde o campo fornecido corresponde a qualquer um dos valores de comparação. Por exemplo:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where('country', 'in', ['USA', 'Japan']));
Web namespaced API
citiesRef.where('country', 'in', ['USA', 'Japan']);
Rápido
let citiesRef = db.collection("cities") citiesRef.whereField("country", in: ["USA", "Japan"])
Objetivo-C
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [citiesRef queryWhereField:@"country" in:@[@"USA", @"Japan"]];
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereIn("country", listOf("USA", "Japan"))
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereIn("country", Arrays.asList("USA", "Japan"));
Dart
final citiesRef = db.collection("cities"); final cities = citiesRef.where("country", whereIn: ["USA", "Japan"]);
Java
Pitão
Python
C++
CollectionReference cities_ref = db->Collection("cities"); cities_ref.WhereIn("country", std::vector<FieldValue> { FieldValue::String("USA"), FieldValue::String("Japan") });
Node.js
Ir
PHP
Unidade
CollectionReference citiesRef = db.Collection("cities"); ListcountriesList = new List<object>() {"USA", "Japan"}; Query whereInQuery = citiesRef.WhereIn("country", countriesList);
C#
Rubi
Esta consulta retorna todos os documentos city
onde o campo country
está definido como USA
ou Japan
. A partir dos dados de exemplo, isso inclui os documentos SF
, LA
, DC
e TOK
.
not-in
Use o operador not-in
para combinar até 10 cláusulas diferentes ( !=
) no mesmo campo com um AND
lógico. Uma consulta not-in
retorna documentos onde o campo fornecido existe, não é null
e não corresponde a nenhum dos valores de comparação. Por exemplo:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where('country', 'not-in', ['USA', 'Japan']));
Web namespaced API
citiesRef.where('country', 'not-in', ['USA', 'Japan']);
Rápido
citiesRef.whereField("country", notIn: ["USA", "Japan"])
Objetivo-C
[citiesRef queryWhereField:@"country" notIn:@[@"USA", @"Japan"]];
Kotlin+KTX
citiesRef.whereNotIn("country", listOf("USA", "Japan"))
Java
citiesRef.whereNotIn("country", Arrays.asList("USA", "Japan"));
Dart
final citiesRef = db.collection("cities"); final cities = citiesRef.where("country", whereNotIn: ["USA", "Japan"]);
Java
Pitão
// Snippet not yet available
C++
cities_ref.WhereNotIn("country", std::vector<FieldValue> { FieldValue::String("USA"), FieldValue::String("Japan") });
Node.js
Ir
// Snippet not yet available
PHP
Unidade
Query query = citiesRef.WhereNotIn(new FieldPath("country"), new List<string>{"USA", "Japan"}); Query query = citiesRef.WhereNotIn("country", new List<object>(){"USA", "Japan"});
C#
// Snippet not yet available
Rubi
Esta consulta retorna todos os documentos city
onde o campo country
existe e não está definido como USA
, Japan
ou null
. A partir dos dados de exemplo, isto inclui os documentos London
e Hong Kong
.
consultas not-in
excluem documentos onde o campo fornecido não existe. Um campo existe quando é definido com qualquer valor, incluindo uma string vazia ( ""
), null
e NaN
(não um número). Observe que x != null
é avaliado como undefined
. Uma consulta not-in
com null
como um dos valores de comparação não corresponde a nenhum documento.
array-contains-any
Use o operador array-contains-any
para combinar até 30 cláusulas array-contains
no mesmo campo com um OR
lógico. Uma consulta array-contains-any
retorna documentos em que o campo fornecido é um array que contém um ou mais dos valores de comparação:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where('regions', 'array-contains-any', ['west_coast', 'east_coast']));
Web namespaced API
citiesRef.where('regions', 'array-contains-any', ['west_coast', 'east_coast']);
Rápido
let citiesRef = db.collection("cities") citiesRef.whereField("regions", arrayContainsAny: ["west_coast", "east_coast"])
Objetivo-C
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [citiesRef queryWhereField:@"regions" arrayContainsAny:@[@"west_coast", @"east_coast"]];
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereArrayContainsAny("regions", listOf("west_coast", "east_coast"))
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereArrayContainsAny("regions", Arrays.asList("west_coast", "east_coast"));
Dart
final citiesRef = db.collection("cities"); final cities = citiesRef .where("regions", arrayContainsAny: ["west_coast", "east_coast"]);
Java
Pitão
Python
C++
CollectionReference cities_ref = db->Collection("cities"); cities_ref.WhereArrayContainsAny("region", std::vector<FieldValue> { FieldValue::String("west_coast"), FieldValue::String("east_coast") });
Node.js
Ir
PHP
Unidade
Query query = citiesRef.WhereArrayContainsAny( "regions", new List<object>() { new List<object>(){"west_coast"}, new List<object>(){"east_coast"}});
C#
Rubi
Esta consulta retorna cada documento de cidade onde o campo regions
é uma matriz que contém west_coast
ou east_coast
. A partir dos dados de exemplo, isso inclui os documentos SF
, LA
e DC
.
Os resultados de array-contains-any
são desduplicados. Mesmo que o campo da matriz de um documento corresponda a mais de um dos valores de comparação, o conjunto de resultados incluirá esse documento apenas uma vez.
array-contains-any
sempre filtra pelo tipo de dados do array. Por exemplo, a consulta acima não retornaria um documento de cidade onde, em vez de uma matriz, o campo regions
é a string west_coast
.
Você pode usar um valor de matriz como valor de comparação para in
, mas diferentemente de array-contains-any
, a cláusula corresponde a uma correspondência exata de comprimento, ordem e valores da matriz. Por exemplo:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where('regions', 'in', [['west_coast'], ['east_coast']]));
Web namespaced API
citiesRef.where('regions', 'in', [['west_coast'], ['east_coast']]);
Rápido
citiesRef.whereField("regions", in: [["west_coast"], ["east_coast"]])
Objetivo-C
[citiesRef queryWhereField:@"regions" in:@[@[@"west_coast"], @[@"east_coast"]]];
Kotlin+KTX
citiesRef.whereIn("regions", listOf(arrayOf("west_coast"), arrayOf("east_coast")))
Java
citiesRef.whereIn("regions", Arrays.asList(new String[]{"west_coast"}, new String[]{"east_coast"}));
Dart
final citiesRef = db.collection("cities"); final cities = citiesRef.where("regions", whereIn: [ ["west_coast"], ["east_coast"] ]);
Java
Pitão
Python
C++
cities_ref.WhereIn("region", std::vector<FieldValue> { FieldValue::String("west_coast"), FieldValue::String("east_coast") });
Node.js
Ir
PHP
Unidade
Query query = citiesRef.WhereIn(new FieldPath("regions"), new List<string>{"west_coast", "east_coast"});
C#
Rubi
Esta consulta retorna cada documento de cidade onde o campo regions
é uma matriz que contém exatamente um elemento de west_coast
ou east_coast
. A partir dos dados de exemplo, apenas o documento DC
se qualifica com seu campo de regions
["east_coast"]
. O documento SF
, no entanto, não corresponde porque seu campo regions
é ["west_coast", "norcal"]
.
Limitações
Observe as seguintes limitações para in
, not-in
e array-contains-any
:
- O Cloud Firestore oferece suporte para consultas lógicas
OR
por meio dos operadoresor
,in
earray-contains-any
. Essas consultas são limitadas a 30 disjunções com base na forma normal disjuntiva da consulta . - Você pode usar no máximo uma cláusula
array-contains
por disjunção (or
grupo). Você não pode combinararray-contains
comarray-contains-any
na mesma disjunção. - Você não pode combinar
not-in
com not equals!=
. -
not-in
suporta até 10 valores de comparação.
Consultas compostas ( AND
)
Você pode combinar restrições com um AND
lógico encadeando vários operadores de igualdade ( ==
ou array-contains
). No entanto, você deve criar um índice composto para combinar operadores de igualdade com os operadores de desigualdade, <
, <=
, >
e !=
.
Web modular API
import { query, where } from "firebase/firestore"; const q1 = query(citiesRef, where("state", "==", "CO"), where("name", "==", "Denver")); const q2 = query(citiesRef, where("state", "==", "CA"), where("population", "<", 1000000));
Web namespaced API
const q1 = citiesRef.where("state", "==", "CO").where("name", "==", "Denver"); const q2 = citiesRef.where("state", "==", "CA").where("population", "<", 1000000);
Rápido
citiesRef .whereField("state", isEqualTo: "CO") .whereField("name", isEqualTo: "Denver") citiesRef .whereField("state", isEqualTo: "CA") .whereField("population", isLessThan: 1000000)
Objetivo-C
[[citiesRef queryWhereField:@"state" isEqualTo:@"CO"] queryWhereField:@"name" isGreaterThanOrEqualTo:@"Denver"]; [[citiesRef queryWhereField:@"state" isEqualTo:@"CA"] queryWhereField:@"population" isLessThan:@1000000];
Kotlin+KTX
citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver") citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000)
Java
citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver"); citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000);
Dart
final citiesRef = db.collection("cities"); citiesRef .where("state", isEqualTo: "CO") .where("name", isEqualTo: "Denver"); citiesRef .where("state", isEqualTo: "CA") .where("population", isLessThan: 1000000);
Java
Pitão
Python
C++
cities_ref.WhereEqualTo("state", FieldValue::String("CO")) .WhereEqualTo("name", FieldValue::String("Denver")); cities_ref.WhereEqualTo("state", FieldValue::String("CA")) .WhereLessThan("population", FieldValue::Integer(1000000));
Node.js
Ir
PHP
Unidade
Query chainedQuery = citiesRef .WhereEqualTo("State", "CA") .WhereEqualTo("Name", "San Francisco");
C#
Rubi
Você pode realizar comparações de intervalo ( <
, <=
, >
, >=
) ou não igual ( !=
) apenas em um único campo e pode incluir no máximo uma cláusula array-contains
ou array-contains-any
em uma consulta composta :
Válido : filtros de intervalo em apenas um campo
Web modular API
import { query, where } from "firebase/firestore"; const q1 = query(citiesRef, where("state", ">=", "CA"), where("state", "<=", "IN")); const q2 = query(citiesRef, where("state", "==", "CA"), where("population", ">", 1000000));
Web namespaced API
const q1 = citiesRef.where("state", ">=", "CA").where("state", "<=", "IN"); const q2 = citiesRef.where("state", "==", "CA").where("population", ">", 1000000);
Rápido
citiesRef .whereField("state", isGreaterThanOrEqualTo: "CA") .whereField("state", isLessThanOrEqualTo: "IN") citiesRef .whereField("state", isEqualTo: "CA") .whereField("population", isGreaterThan: 1000000)
Objetivo-C
[[citiesRef queryWhereField:@"state" isGreaterThanOrEqualTo:@"CA"] queryWhereField:@"state" isLessThanOrEqualTo:@"IN"]; [[citiesRef queryWhereField:@"state" isEqualTo:@"CA"] queryWhereField:@"population" isGreaterThan:@1000000];
Kotlin+KTX
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereLessThanOrEqualTo("state", "IN") citiesRef.whereEqualTo("state", "CA") .whereGreaterThan("population", 1000000)
Java
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereLessThanOrEqualTo("state", "IN"); citiesRef.whereEqualTo("state", "CA") .whereGreaterThan("population", 1000000);
Dart
final citiesRef = db.collection("cities"); citiesRef .where("state", isGreaterThanOrEqualTo: "CA") .where("state", isLessThanOrEqualTo: "IN"); citiesRef .where("state", isEqualTo: "CA") .where("population", isGreaterThan: 1000000);
Java
Pitão
Python
C++
cities_ref.WhereGreaterThanOrEqualTo("state", FieldValue::String("CA")) .WhereLessThanOrEqualTo("state", FieldValue::String("IN")); cities_ref.WhereEqualTo("state", FieldValue::String("CA")) .WhereGreaterThan("population", FieldValue::Integer(1000000));
Node.js
Ir
PHP
Unidade
Query rangeQuery = citiesRef .WhereGreaterThanOrEqualTo("State", "CA") .WhereLessThanOrEqualTo("State", "IN");
C#
Rubi
Inválido : filtros de intervalo em campos diferentes
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where("state", ">=", "CA"), where("population", ">", 100000));
Web namespaced API
citiesRef.where("state", ">=", "CA").where("population", ">", 100000);
Rápido
citiesRef .whereField("state", isGreaterThanOrEqualTo: "CA") .whereField("population", isGreaterThan: 1000000)
Objetivo-C
[[citiesRef queryWhereField:@"state" isGreaterThanOrEqualTo:@"CA"] queryWhereField:@"population" isGreaterThan:@1000000];
Kotlin+KTX
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereGreaterThan("population", 100000)
Java
citiesRef.whereGreaterThanOrEqualTo("state", "CA").whereGreaterThan("population", 100000);
Dart
final citiesRef = db.collection("cities"); citiesRef .where("state", isGreaterThanOrEqualTo: "CA") .where("population", isGreaterThan: 1000000);
Java
Pitão
Python
C++
// BAD EXAMPLE -- will crash the program: cities_ref.WhereGreaterThanOrEqualTo("state", FieldValue::String("CA")) .WhereGreaterThan("population", FieldValue::Integer(100000));
Node.js
Ir
PHP
Unidade
Query invalidRangeQuery = citiesRef .WhereGreaterThanOrEqualTo("State", "CA") .WhereGreaterThan("Population", 1000000);
C#
Rubi
OR
consultas
Você pode combinar restrições com um OR
lógico. Por exemplo:
Web modular API
const q = query(citiesRef, or(where('capital', '==', true), where('population', '>=', 1000000) ) );
Web namespaced API
Não disponível.
Rápido
let query = db.collection("cities").whereFilter(Filter.orFilter([ Filter.whereField("capital", isEqualTo: true), Filter.whereField("population", isGreaterThanOrEqualTo: 1000000); ]))
Objetivo-C
FIRCollectionReference *collection = [self.db collectionWithPath:@"cities"]; FIRQuery *query = [collection queryWhereFilter:[FIRFilter orFilterWithFilters:@[ [FIRFilter filterWhereField:@"capital" isEqualTo:@YES], [FIRFilter filterWhereField:@"population" isGreaterThanOrEqualTo:@1000000] ]]];
Kotlin+KTX
val query = collection.where(Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ))
Java
Query query = collection.where(Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ));
Dart
var query = db.collection("cities") .where( Filter.or( Filter("capital", isEqualTo: true), Filter("population", isGreaterThan: 1000000) ));
Java
Trecho não disponível.
Pitão
Python
Trecho não disponível.
C++
Trecho não disponível.
Node.js
const bigCities = await citiesRef .where( Filter.or( Filter.where('capital', '==', true), Filter.where('population', '>=', 1000000) ) ) .get();
Ir
PHP
Trecho não disponível.
Unidade
Query query = citiesRef.Where(Filter.Or( Filter.EqualTo("State", "CA"), Filter.GreaterThanOrEqualTo("population", 1000000) )); query.GetSnapshotAsync().ContinueWithOnMainThread((querySnapshotTask) => { foreach (DocumentSnapshot documentSnapshot in querySnapshotTask.Result.Documents) { Debug.Log(String.Format("Document {0} returned by query State=CA or population >= {1}", documentSnapshot.Id, 1000000)); } });
C#
Trecho não disponível.
Rubi
Trecho não disponível.
O Cloud Firestore usa seus índices compostos para atender consultas OR
. Se seus índices não suportarem a consulta, o Cloud Firestore sugerirá índices adicionais para seu banco de dados .
Você pode combinar consultas OR
com consultas compostas para filtrar combinações de operações OR
e AND
. Por exemplo:
Web modular API
const q = query(collection(db, "cities"), and( where('state', '==', 'CA'), or( where('capital', '==', true), where('population', '>=', 1000000) ) ));
Web namespaced API
Não disponível.
Rápido
let query = db.collection("cities").whereFilter(Filter.andFilter([ Filter.whereField("state", isEqualTo: "CA"), Filter.orFilter([ Filter.whereField("capital", isEqualTo: true), Filter.whereField("population", isGreaterThanOrEqualTo: 1000000); ]) ]))
Objetivo-C
FIRCollectionReference *collection = [self.db collectionWithPath:@"cities"]; FIRQuery *query = [collection queryWhereFilter:[FIRFilter andFilterWithFilters:@[ [FIRFilter filterWhereField:@"state" isEqualTo:@"CA"], [FIRFilter orFilterWithFilters:@[ [FIRFilter filterWhereField:@"capital" isEqualTo:@YES], [FIRFilter filterWhereField:@"population" isGreaterThanOrEqualTo:@1000000] ]] ]]];
Kotlin+KTX
val query = collection.where(Filter.and( Filter.equalTo("state", "CA"), Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ) ))
Java
Query query = collection.where(Filter.and( Filter.equalTo("state", "CA"), Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ) ));
Dart
var query = db.collection("cities") .where( Filter.and( Filter("state", isEqualTo: "CA"), Filter.or( Filter("capital", isEqualTo: true), Filter("population", isGreaterThan: 1000000) )));
Java
Trecho não disponível.
Pitão
Trecho não disponível.
Python
Trecho não disponível.
C++
Trecho não disponível.
Node.js
const bigCitiesInCalifornia = await citiesRef .where('state', '==', 'CA') .where( Filter.or( Filter.where('capital', '==', true), Filter.where('population', '>=', 1000000) ) ) .get();
Ir
Trecho não disponível.
PHP
Trecho não disponível.
Unidade
Query query = citiesRef.Where(Filter.And( Filter.EqualTo("state", "CA"), Filter.Or( Filter.EqualTo("capital", true), Filter.GreaterThanOrEqualTo("population", 1000000) ) ));
C#
Trecho não disponível.
Rubi
Trecho não disponível.
Limitações
Observe as seguintes limitações para consultas or
:
- O Cloud Firestore limita uma consulta a um máximo de 30 disjunções com base na forma normal disjuntiva da consulta . É mais provável que você atinja esse limite ao executar um
AND
de vários gruposOR
. - Você não pode combinar
not-in
comin
,array-contains-any
ouor
na mesma consulta.
Para obter uma descrição completa das limitações, consulte Limitações de consulta .
Consultas de grupo de coleções
Um grupo de coleções consiste em todas as coleções com o mesmo ID. Por padrão, as consultas recuperam resultados de uma única coleção no seu banco de dados. Utilize uma consulta de grupo de coleções para recuperar documentos de um grupo de coleções em vez de uma única coleção.
Por exemplo, você pode criar um grupo de coleções landmarks
adicionando uma subcoleção de pontos de referência a cada cidade:
Web modular API
import { collection, addDoc } from "firebase/firestore"; const citiesRef = collection(db, 'cities'); await Promise.all([ addDoc(collection(citiesRef, 'SF', 'landmarks'), { name: 'Golden Gate Bridge', type: 'bridge' }), addDoc(collection(citiesRef, 'SF', 'landmarks'), { name: 'Legion of Honor', type: 'museum' }), addDoc(collection(citiesRef, 'LA', 'landmarks'), { name: 'Griffith Park', type: 'park' }), addDoc(collection(citiesRef, 'LA', 'landmarks'), { name: 'The Getty', type: 'museum' }), addDoc(collection(citiesRef, 'DC', 'landmarks'), { name: 'Lincoln Memorial', type: 'memorial' }), addDoc(collection(citiesRef, 'DC', 'landmarks'), { name: 'National Air and Space Museum', type: 'museum' }), addDoc(collection(citiesRef, 'TOK', 'landmarks'), { name: 'Ueno Park', type: 'park' }), addDoc(collection(citiesRef, 'TOK', 'landmarks'), { name: 'National Museum of Nature and Science', type: 'museum' }), addDoc(collection(citiesRef, 'BJ', 'landmarks'), { name: 'Jingshan Park', type: 'park' }), addDoc(collection(citiesRef, 'BJ', 'landmarks'), { name: 'Beijing Ancient Observatory', type: 'museum' }) ]);
Web namespaced API
var citiesRef = db.collection('cities'); var landmarks = Promise.all([ citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Golden Gate Bridge', type: 'bridge' }), citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Legion of Honor', type: 'museum' }), citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'Griffith Park', type: 'park' }), citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'The Getty', type: 'museum' }), citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'Lincoln Memorial', type: 'memorial' }), citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'National Air and Space Museum', type: 'museum' }), citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'Ueno Park', type: 'park' }), citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'National Museum of Nature and Science', type: 'museum' }), citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Jingshan Park', type: 'park' }), citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Beijing Ancient Observatory', type: 'museum' }) ]);
Rápido
let citiesRef = db.collection("cities") var data = ["name": "Golden Gate Bridge", "type": "bridge"] citiesRef.document("SF").collection("landmarks").addDocument(data: data) data = ["name": "Legion of Honor", "type": "museum"] citiesRef.document("SF").collection("landmarks").addDocument(data: data) data = ["name": "Griffith Park", "type": "park"] citiesRef.document("LA").collection("landmarks").addDocument(data: data) data = ["name": "The Getty", "type": "museum"] citiesRef.document("LA").collection("landmarks").addDocument(data: data) data = ["name": "Lincoln Memorial", "type": "memorial"] citiesRef.document("DC").collection("landmarks").addDocument(data: data) data = ["name": "National Air and Space Museum", "type": "museum"] citiesRef.document("DC").collection("landmarks").addDocument(data: data) data = ["name": "Ueno Park", "type": "park"] citiesRef.document("TOK").collection("landmarks").addDocument(data: data) data = ["name": "National Museum of Nature and Science", "type": "museum"] citiesRef.document("TOK").collection("landmarks").addDocument(data: data) data = ["name": "Jingshan Park", "type": "park"] citiesRef.document("BJ").collection("landmarks").addDocument(data: data) data = ["name": "Beijing Ancient Observatory", "type": "museum"] citiesRef.document("BJ").collection("landmarks").addDocument(data: data)
Objetivo-C
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; NSDictionary *data = @{@"name": @"Golden Gate Bridge", @"type": @"bridge"}; [[[citiesRef documentWithPath:@"SF"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Legion of Honor", @"type": @"museum"}; [[[citiesRef documentWithPath:@"SF"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Griffith Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"LA"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"The Getty", @"type": @"museum"}; [[[citiesRef documentWithPath:@"LA"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Lincoln Memorial", @"type": @"memorial"}; [[[citiesRef documentWithPath:@"DC"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"National Air and Space Museum", @"type": @"museum"}; [[[citiesRef documentWithPath:@"DC"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Ueno Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"TOK"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"National Museum of Nature and Science", @"type": @"museum"}; [[[citiesRef documentWithPath:@"TOK"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Jingshan Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"BJ"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Beijing Ancient Observatory", @"type": @"museum"}; [[[citiesRef documentWithPath:@"BJ"] collectionWithPath:@"landmarks"] addDocumentWithData:data];
Kotlin+KTX
val citiesRef = db.collection("cities") val ggbData = mapOf( "name" to "Golden Gate Bridge", "type" to "bridge", ) citiesRef.document("SF").collection("landmarks").add(ggbData) val lohData = mapOf( "name" to "Legion of Honor", "type" to "museum", ) citiesRef.document("SF").collection("landmarks").add(lohData) val gpData = mapOf( "name" to "Griffth Park", "type" to "park", ) citiesRef.document("LA").collection("landmarks").add(gpData) val tgData = mapOf( "name" to "The Getty", "type" to "museum", ) citiesRef.document("LA").collection("landmarks").add(tgData) val lmData = mapOf( "name" to "Lincoln Memorial", "type" to "memorial", ) citiesRef.document("DC").collection("landmarks").add(lmData) val nasaData = mapOf( "name" to "National Air and Space Museum", "type" to "museum", ) citiesRef.document("DC").collection("landmarks").add(nasaData) val upData = mapOf( "name" to "Ueno Park", "type" to "park", ) citiesRef.document("TOK").collection("landmarks").add(upData) val nmData = mapOf( "name" to "National Musuem of Nature and Science", "type" to "museum", ) citiesRef.document("TOK").collection("landmarks").add(nmData) val jpData = mapOf( "name" to "Jingshan Park", "type" to "park", ) citiesRef.document("BJ").collection("landmarks").add(jpData) val baoData = mapOf( "name" to "Beijing Ancient Observatory", "type" to "musuem", ) citiesRef.document("BJ").collection("landmarks").add(baoData)
Java
CollectionReference citiesRef = db.collection("cities"); Map<String, Object> ggbData = new HashMap<>(); ggbData.put("name", "Golden Gate Bridge"); ggbData.put("type", "bridge"); citiesRef.document("SF").collection("landmarks").add(ggbData); Map<String, Object> lohData = new HashMap<>(); lohData.put("name", "Legion of Honor"); lohData.put("type", "museum"); citiesRef.document("SF").collection("landmarks").add(lohData); Map<String, Object> gpData = new HashMap<>(); gpData.put("name", "Griffith Park"); gpData.put("type", "park"); citiesRef.document("LA").collection("landmarks").add(gpData); Map<String, Object> tgData = new HashMap<>(); tgData.put("name", "The Getty"); tgData.put("type", "museum"); citiesRef.document("LA").collection("landmarks").add(tgData); Map<String, Object> lmData = new HashMap<>(); lmData.put("name", "Lincoln Memorial"); lmData.put("type", "memorial"); citiesRef.document("DC").collection("landmarks").add(lmData); Map<String, Object> nasaData = new HashMap<>(); nasaData.put("name", "National Air and Space Museum"); nasaData.put("type", "museum"); citiesRef.document("DC").collection("landmarks").add(nasaData); Map<String, Object> upData = new HashMap<>(); upData.put("name", "Ueno Park"); upData.put("type", "park"); citiesRef.document("TOK").collection("landmarks").add(upData); Map<String, Object> nmData = new HashMap<>(); nmData.put("name", "National Museum of Nature and Science"); nmData.put("type", "museum"); citiesRef.document("TOK").collection("landmarks").add(nmData); Map<String, Object> jpData = new HashMap<>(); jpData.put("name", "Jingshan Park"); jpData.put("type", "park"); citiesRef.document("BJ").collection("landmarks").add(jpData); Map<String, Object> baoData = new HashMap<>(); baoData.put("name", "Beijing Ancient Observatory"); baoData.put("type", "museum"); citiesRef.document("BJ").collection("landmarks").add(baoData);
Dart
final citiesRef = db.collection("cities"); final ggbData = {"name": "Golden Gate Bridge", "type": "bridge"}; citiesRef.doc("SF").collection("landmarks").add(ggbData); final lohData = {"name": "Legion of Honor", "type": "museum"}; citiesRef.doc("SF").collection("landmarks").add(lohData); final gpData = {"name": "Griffth Park", "type": "park"}; citiesRef.doc("LA").collection("landmarks").add(gpData); final tgData = {"name": "The Getty", "type": "museum"}; citiesRef.doc("LA").collection("landmarks").add(tgData); final lmData = {"name": "Lincoln Memorial", "type": "memorial"}; citiesRef.doc("DC").collection("landmarks").add(lmData); final nasaData = { "name": "National Air and Space Museum", "type": "museum" }; citiesRef.doc("DC").collection("landmarks").add(nasaData); final upData = {"name": "Ueno Park", "type": "park"}; citiesRef.doc("TOK").collection("landmarks").add(upData); final nmData = { "name": "National Musuem of Nature and Science", "type": "museum" }; citiesRef.doc("TOK").collection("landmarks").add(nmData); final jpData = {"name": "Jingshan Park", "type": "park"}; citiesRef.doc("BJ").collection("landmarks").add(jpData); final baoData = {"name": "Beijing Ancient Observatory", "type": "musuem"}; citiesRef.doc("BJ").collection("landmarks").add(baoData);
Java
Pitão
Python
C++
// Get a new write batch WriteBatch batch = db->batch(); DocumentReference sf_ref = db->Collection("cities").Document("SF"); batch.Set(sf_ref,{{"name", FieldValue::String("Golden Gate Bridge")}, {"type", FieldValue::String("bridge")}}); batch.Set(sf_ref,{{"name", FieldValue::String("Legion of Honor")}, {"type", FieldValue::String("museum")}}); DocumentReference la_ref = db->Collection("cities").Document("LA"); batch.Set(la_ref,{{"name", FieldValue::String("Griffith Park")}, {"type", FieldValue::String("park")}}); batch.Set(la_ref,{{"name", FieldValue::String("The Getty")}, {"type", FieldValue::String("museum")}}); DocumentReference dc_ref = db->Collection("cities").Document("DC"); batch.Set(dc_ref,{{"name", FieldValue::String("Lincoln Memorial")}, {"type", FieldValue::String("memorial")}}); batch.Set(dc_ref,{{"name", FieldValue::String("National Air and Space Museum")}, {"type", FieldValue::String("museum")}}); DocumentReference tok_ref = db->Collection("cities").Document("TOK"); batch.Set(tok_ref,{{"name", FieldValue::String("Ueno Park")}, {"type", FieldValue::String("park")}}); batch.Set(tok_ref,{{"name", FieldValue::String("National Museum of Nature and Science")}, {"type", FieldValue::String("museum")}}); DocumentReference bj_ref = db->Collection("cities").Document("BJ"); batch.Set(bj_ref,{{"name", FieldValue::String("Jingshan Park")}, {"type", FieldValue::String("park")}}); batch.Set(bj_ref,{{"name", FieldValue::String("Beijing Ancient Observatory")}, {"type", FieldValue::String("museum")}}); // Commit the batch batch.Commit().OnCompletion([](const Future<void>& future) { if (future.error() == Error::kErrorOk) { std::cout << "Write batch success!" << std::endl; } else { std::cout << "Write batch failure: " << future.error_message() << std::endl; } });
Node.js
Ir
PHP
Unidade
List<Task<DocumentReference>> futures = new List<Task<DocumentReference>>(){ citiesRef .Document("SF") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "Golden Gate Bridge"}, {"type", "bridge"}, } ), citiesRef .Document("SF") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "Legion of Honor"}, {"type", "museum"}, } ), citiesRef .Document("LA") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "Griffith Park"}, {"type", "park"}, } ), citiesRef .Document("LA") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "The Getty"}, {"type", "museum"}, } ), citiesRef .Document("DC") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "Lincoln Memorial"}, {"type", "memorial"}, } ), citiesRef .Document("DC") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "National Air and Space Museum"}, {"type", "museum"}, } ), citiesRef .Document("TOK") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "Ueno Park"}, {"type", "park"}, } ), citiesRef .Document("TOK") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "National Museum of Nature and Science"}, {"type", "museum"}, } ), citiesRef .Document("BJ") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "Jingshan Park"}, {"type", "park"}, } ), citiesRef .Document("BJ") .Collection("landmarks") .AddAsync( new Dictionary<string, object>() { {"name", "Beijing Ancient Observatory"}, {"type", "museum"}, } )}; DocumentReference[] landmarks = Task.WhenAll(futures).Result;
C#
Rubi
Podemos usar a consulta simples e composta descrita anteriormente para consultar a subcoleção landmarks
de uma única cidade, mas você também pode querer recuperar os resultados da subcoleção de landmarks
de cada cidade de uma só vez.
O grupo de coleções landmarks
consiste em todas as coleções com o ID landmarks
e você pode consultá-lo usando uma consulta de grupo de coleções. Por exemplo, esta consulta de grupo de coleções recupera todos os pontos de referência museum
em todas as cidades:
Web modular API
import { collectionGroup, query, where, getDocs } from "firebase/firestore"; const museums = query(collectionGroup(db, 'landmarks'), where('type', '==', 'museum')); const querySnapshot = await getDocs(museums); querySnapshot.forEach((doc) => { console.log(doc.id, ' => ', doc.data()); });
Web namespaced API
var museums = db.collectionGroup('landmarks').where('type', '==', 'museum'); museums.get().then((querySnapshot) => { querySnapshot.forEach((doc) => { console.log(doc.id, ' => ', doc.data()); }); });
Rápido
db.collectionGroup("landmarks").whereField("type", isEqualTo: "museum").getDocuments { (snapshot, error) in // ... }
Objetivo-C
[[[self.db collectionGroupWithID:@"landmarks"] queryWhereField:@"type" isEqualTo:@"museum"] getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) { // ... }];
Kotlin+KTX
db.collectionGroup("landmarks").whereEqualTo("type", "museum").get() .addOnSuccessListener { queryDocumentSnapshots -> // ... }
Java
db.collectionGroup("landmarks").whereEqualTo("type", "museum").get() .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() { @Override public void onSuccess(QuerySnapshot queryDocumentSnapshots) { // ... } });
Dart
db .collectionGroup("landmarks") .where("type", isEqualTo: "museum") .get() .then( (res) => print("Successfully completed"), onError: (e) => print("Error completing: $e"), );
Java
Pitão
Python
C++
db->CollectionGroup("landmarks") .WhereEqualTo("type", FieldValue::String("museum")).Get() .OnCompletion([](const firebase::Future<QuerySnapshot>& future) { if (future.error() == Error::kErrorOk) { for (const DocumentSnapshot& document : future.result()->documents()) { std::cout << document << std::endl; } } else { std::cout << "Error getting documents: " << future.error_message() << std::endl; } });
Node.js
Ir
PHP
Unidade
Query museums = db.CollectionGroup("landmarks").WhereEqualTo("type", "museum"); museums.GetSnapshotAsync().ContinueWithOnMainThread((querySnapshotTask) => { foreach (DocumentSnapshot documentSnapshot in querySnapshotTask.Result.Documents) { Debug.Log(String.Format("Document {0} returned by query State=CA", documentSnapshot.Id)); } });
C#
Rubi
Antes de usar uma consulta de grupo de coleções, você deve criar um índice que suporte sua consulta de grupo de coleções. Você pode criar um índice por meio de uma mensagem de erro, do console ou da CLI do Firebase .
Para os SDKs da Web e de dispositivos móveis, você também deve criar regras que permitam consultas de grupos de coleções .
Limitações de consulta
A lista a seguir resume as limitações de consulta do Cloud Firestore:
- O Cloud Firestore oferece suporte para consultas lógicas
OR
por meio dos operadoresor
,in
earray-contains-any
. Essas consultas são limitadas a 30 disjunções com base na forma normal disjuntiva da consulta . - Em uma consulta composta, as comparações de intervalo (
<
,<=
,>
,>=
) e não iguais (!=
,not-in
) devem ser filtradas no mesmo campo. - Você pode usar no máximo uma cláusula
array-contains
por disjunção (or
grupo). Você não pode combinararray-contains
comarray-contains-any
na mesma disjunção. - Você não pode combinar
not-in
comin
,array-contains-any
ouor
na mesma consulta. - Apenas um único
not-in
ou!=
` é permitido por consulta. -
not-in
suporta até 10 valores de comparação. - A soma dos filtros, ordens de classificação e caminho do documento pai (1 para uma subcoleção, 0 para uma coleção raiz) em uma consulta não pode exceder 100. Isso é calculado com base na forma normal disjuntiva da consulta .
- Uma consulta com um filtro de desigualdade em um campo implica ordenação por esse campo e filtros para a existência desse campo .
Limites em consultas OR
Para evitar que uma consulta se torne muito cara em termos computacionais, o Cloud Firestore limita quantas cláusulas AND
e OR
você pode combinar. Para aplicar esse limite, o Cloud Firestore converte consultas que executam operações lógicas OR
( or
, in
e array-contains-any
) na forma normal disjuntiva (também conhecida como OR
de AND
s). O Cloud Firestore limita uma consulta a um máximo de 30 disjunções na forma normal disjuntiva.
Forma normal disjuntiva
O Cloud Firestore converte consultas para a forma normal disjuntiva aplicando duas regras:
Achatar
Dadas as condições
A
,B
eC
:A and (B and C) => A and B and C
Dadas as condições
A
,B
,C
eD
:-
A and (B or C) => (A and B) or (A and C)
-
(A or B) and (C or D) => (A and C) or (A and D) or (B and C) or (B and D)
-
Ao aplicar essas regras a consultas in
e array-contains-any
, lembre-se de que esses operadores são abreviações para OR
. Por exemplo, a in [1,2]
é uma abreviação de a = 1 OR a = 2
.
Os exemplos a seguir mostram o número de disjunções para diferentes consultas:
Consulta | Número de disjunções |
---|---|
query(collectionRef, where("a", "==", 1)) | 1 |
query(collectionRef, or( where("a", "==", 1), where("b", "==", 2) )) | 2 |
query(collectionRef, or( and( where("a", "==", 1), where("c", "==", 3) ), and( where("a", "==", 1), where("d", "==", 4) ), and( where("b", "==", 2), where("c", "==", 3) ), and( where("b", "==", 2), where("d", "==", 4) ) ) ) | 4 |
query(collectionRef, and( or( where("a", "==", 1), where("b", "==", 2) ), or( where("c", "==", 3), where("d", "==", 4) ) ) ) | 4 A forma normal disjuntiva desta consulta é igual à consulta acima. |
query(collectionRef, where("a", "in", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ) | 10 |
query(collectionRef, and( where("a", "in", [1, 2, 3, 4, 5]), where("b", "in", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ) ) | 50 Esta consulta retorna um erro, pois ultrapassa o limite de 30 disjunções. |
query(collectionRef, or( where("a", "in", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), where("b", "in", [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ) ) | 20 |
query(collectionRef, and( where("a", "in", [1, 2, 3, 4, 5]), or( where("b", "==", 2), where("c", "==", 3) ) ) ) | 10 |
orderBy
e existência
Quando você ordena uma consulta por um determinado campo, a consulta pode retornar apenas os documentos onde existe o campo ordenado por.
Por exemplo, a consulta a seguir não retornaria nenhum documento cujo campo population
não estivesse definido, mesmo que eles atendessem aos filtros da consulta.
Java
db.collection("cities").whereEqualTo("country", “USA”).orderBy(“population”);
Um efeito relacionado aplica-se às desigualdades. Uma consulta com filtro de desigualdade em um campo também implica ordenação por esse campo. A consulta a seguir não retorna documentos sem um campo population
mesmo se country = USA
nesse documento. Como solução alternativa, você pode executar consultas separadas para cada ordenação ou pode atribuir um valor para todos os campos ordenados.
Java
db.collection(“cities”).where(or(“country”, USA”), greaterThan(“population”, 250000));
A consulta acima inclui uma ordem implícita na desigualdade e é equivalente ao seguinte:
Java
db.collection(“cities”).where(or(“country”, USA”), greaterThan(“population”, 250000)).orderBy(“population”);
Qual é o próximo
- Saiba como ordenar e limitar dados nos resultados da consulta .
- Salve leituras quando quiser simplesmente contar os resultados .