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:
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"] });
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"] });
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"]
])
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"]
}];
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)
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);
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);
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()
)
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()
)
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")})},
});
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"} }
});
Consultas simples
A consulta a seguir retorna todas as cidades com estado CA
:
// 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"));
// Create a reference to the cities collection
var citiesRef = db.collection("cities");
// Create a query against the collection.
var query = citiesRef.where("state", "==", "CA");
// 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")
// 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"];
// Create a reference to the cities collection
val citiesRef = db.collection("cities")
// Create a query against the collection.
val query = citiesRef.whereEqualTo("state", "CA")
// Create a reference to the cities collection
CollectionReference citiesRef = db.collection("cities");
// Create a query against the collection.
Query query = citiesRef.whereEqualTo("state", "CA");
// 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");
CollectionReference cities_ref = db->Collection("cities");
// Create a query against the collection.
Query query_ca =
cities_ref.WhereEqualTo("state", FieldValue::String("CA"));
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));
}
});
A consulta a seguir retorna todas as capitais:
import { collection, query, where } from "firebase/firestore";
const citiesRef = collection(db, "cities");
const q = query(citiesRef, where("capital", "==", true));
var citiesRef = db.collection("cities");
var query = citiesRef.where("capital", "==", true);
let capitalCities = db.collection("cities").whereField("capital", isEqualTo: true)
FIRQuery *capitalCities =
[[self.db collectionWithPath:@"cities"] queryWhereField:@"capital" isEqualTo:@YES];
val capitalCities = db.collection("cities").whereEqualTo("capital", true)
Query capitalCities = db.collection("cities").whereEqualTo("capital", true);
final capitalcities =
db.collection("cities").where("capital", isEqualTo: true);
Query capital_cities = db->Collection("cities").WhereEqualTo(
"capital", FieldValue::Boolean(true));
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));
}
});
Executar uma consulta
Após criar um objeto de consulta, use a função get()
para recuperar os resultados:
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());
});
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);
});
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)")
}
[[[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);
}
}
}];
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)
}
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());
}
}
});
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"),
);
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;
}
});
PHP
Para obter mais informações sobre como instalar e criar um cliente Cloud Firestore, consulte Bibliotecas de cliente Cloud Firestore .
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("");
};
});
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:
const stateQuery = query(citiesRef, where("state", "==", "CA"));
const populationQuery = query(citiesRef, where("population", "<", 100000));
const nameQuery = query(citiesRef, where("name", ">=", "San Francisco"));
const stateQuery = citiesRef.where("state", "==", "CA");
const populationQuery = citiesRef.where("population", "<", 100000);
const nameQuery = citiesRef.where("name", ">=", "San Francisco");
let stateQuery = citiesRef.whereField("state", isEqualTo: "CA")
let populationQuery = citiesRef.whereField("population", isLessThan: 100000)
let nameQuery = citiesRef.whereField("name", isGreaterThanOrEqualTo: "San Francisco")
FIRQuery *stateQuery = [citiesRef queryWhereField:@"state" isEqualTo:@"CA"];
FIRQuery *populationQuery = [citiesRef queryWhereField:@"population" isLessThan:@100000];
FIRQuery *nameQuery = [citiesRef queryWhereField:@"name" isGreaterThanOrEqualTo:@"San Francisco"];
val stateQuery = citiesRef.whereEqualTo("state", "CA")
val populationQuery = citiesRef.whereLessThan("population", 100000)
val nameQuery = citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco")
Query stateQuery = citiesRef.whereEqualTo("state", "CA");
Query populationQuery = citiesRef.whereLessThan("population", 100000);
Query nameQuery = citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco");
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");
cities_ref.WhereEqualTo("state", FieldValue::String("CA"));
cities_ref.WhereLessThan("population", FieldValue::Integer(100000));
cities_ref.WhereGreaterThanOrEqualTo("name",
FieldValue::String("San Francisco"));
Query stateQuery = citiesRef.WhereEqualTo("State", "CA");
Query populationQuery = citiesRef.WhereGreaterThan("Population", 1000000);
Query nameQuery = citiesRef.WhereGreaterThanOrEqualTo("Name", "San Francisco");
Diferente ( !=
)
Use o operador diferente ( !=
) para retornar documentos onde o campo fornecido existe e não corresponde ao valor de comparação. Por exemplo:
const notCapitalQuery = query(citiesRef, where("capital", "!=", false));
citiesRef.where("capital", "!=", false);
let notEqualQuery = citiesRef.whereField("capital", isNotEqualTo: false)
query = [citiesRef queryWhereField:@"capital" isNotEqualTo:@NO];
val notCapitalQuery = citiesRef.whereNotEqualTo("capital", false)
Query notCapitalQuery = citiesRef.whereNotEqualTo("capital", false);
final citiesRef = db.collection("cities");
final notCapitals = citiesRef.where("capital", isNotEqualTo: true);
// Snippet not yet available
// Snippet not yet available
Query query = citiesRef.WhereNotEqualTo("capital", false);
Query query = citiesRef.WhereNotEqualTo("capital", false);
// Snippet not yet available
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:
import { query, where } from "firebase/firestore";
const q = query(citiesRef, where("regions", "array-contains", "west_coast"));
citiesRef.where("regions", "array-contains", "west_coast");
citiesRef
.whereField("regions", arrayContains: "west_coast")
[citiesRef queryWhereField:@"state" arrayContains:@"west_coast"];
val citiesRef = db.collection("cities")
citiesRef.whereArrayContains("regions", "west_coast")
CollectionReference citiesRef = db.collection("cities");
citiesRef.whereArrayContains("regions", "west_coast");
final citiesRef = db.collection("cities");
final westCoastcities =
citiesRef.where("regions", arrayContains: "west_coast");
CollectionReference cities_ref = db->Collection("cities");
cities_ref.WhereArrayContains("region", FieldValue::String("west_coast"));
CollectionReference citiesRef = db.Collection("cities");
Query arrayContainsQuery = citiesRef.WhereArrayContains("region", "west_coast");
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:
import { query, where } from "firebase/firestore";
const q = query(citiesRef, where('country', 'in', ['USA', 'Japan']));
citiesRef.where('country', 'in', ['USA', 'Japan']);
let citiesRef = db.collection("cities")
citiesRef.whereField("country", in: ["USA", "Japan"])
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"];
[citiesRef queryWhereField:@"country" in:@[@"USA", @"Japan"]];
val citiesRef = db.collection("cities")
citiesRef.whereIn("country", listOf("USA", "Japan"))
CollectionReference citiesRef = db.collection("cities");
citiesRef.whereIn("country", Arrays.asList("USA", "Japan"));
final citiesRef = db.collection("cities");
final cities = citiesRef.where("country", whereIn: ["USA", "Japan"]);
CollectionReference cities_ref = db->Collection("cities");
cities_ref.WhereIn("country", std::vector<FieldValue> {
FieldValue::String("USA"),
FieldValue::String("Japan")
});
CollectionReference citiesRef = db.Collection("cities");
List
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:
import { query, where } from "firebase/firestore";
const q = query(citiesRef, where('country', 'not-in', ['USA', 'Japan']));
citiesRef.where('country', 'not-in', ['USA', 'Japan']);
citiesRef.whereField("country", notIn: ["USA", "Japan"])
[citiesRef queryWhereField:@"country" notIn:@[@"USA", @"Japan"]];
citiesRef.whereNotIn("country", listOf("USA", "Japan"))
citiesRef.whereNotIn("country", Arrays.asList("USA", "Japan"));
final citiesRef = db.collection("cities");
final cities = citiesRef.where("country", whereNotIn: ["USA", "Japan"]);
// Snippet not yet available
cities_ref.WhereNotIn("country", std::vector<FieldValue> {
FieldValue::String("USA"),
FieldValue::String("Japan")
});
// Snippet not yet available
Query query = citiesRef.WhereNotIn(new FieldPath("country"), new List<string>{"USA", "Japan"});
Query query = citiesRef.WhereNotIn("country", new List<object>(){"USA", "Japan"});
// Snippet not yet available
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:
import { query, where } from "firebase/firestore";
const q = query(citiesRef,
where('regions', 'array-contains-any', ['west_coast', 'east_coast']));
citiesRef.where('regions', 'array-contains-any',
['west_coast', 'east_coast']);
let citiesRef = db.collection("cities")
citiesRef.whereField("regions", arrayContainsAny: ["west_coast", "east_coast"])
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"];
[citiesRef queryWhereField:@"regions" arrayContainsAny:@[@"west_coast", @"east_coast"]];
val citiesRef = db.collection("cities")
citiesRef.whereArrayContainsAny("regions", listOf("west_coast", "east_coast"))
CollectionReference citiesRef = db.collection("cities");
citiesRef.whereArrayContainsAny("regions", Arrays.asList("west_coast", "east_coast"));
final citiesRef = db.collection("cities");
final cities = citiesRef
.where("regions", arrayContainsAny: ["west_coast", "east_coast"]);
CollectionReference cities_ref = db->Collection("cities");
cities_ref.WhereArrayContainsAny("region", std::vector<FieldValue> {
FieldValue::String("west_coast"),
FieldValue::String("east_coast")
});
Query query = citiesRef.WhereArrayContainsAny(
"regions",
new List<object>()
{
new List<object>(){"west_coast"},
new List<object>(){"east_coast"}});
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:
import { query, where } from "firebase/firestore";
const q = query(citiesRef, where('regions', 'in', [['west_coast'], ['east_coast']]));
citiesRef.where('regions', 'in',
[['west_coast'], ['east_coast']]);
citiesRef.whereField("regions", in: [["west_coast"], ["east_coast"]])
[citiesRef queryWhereField:@"regions" in:@[@[@"west_coast"], @[@"east_coast"]]];
citiesRef.whereIn("regions", listOf(arrayOf("west_coast"), arrayOf("east_coast")))
citiesRef.whereIn("regions", Arrays.asList(new String[]{"west_coast"}, new String[]{"east_coast"}));
final citiesRef = db.collection("cities");
final cities = citiesRef.where("regions", whereIn: [
["west_coast"],
["east_coast"]
]);
cities_ref.WhereIn("region", std::vector<FieldValue> {
FieldValue::String("west_coast"),
FieldValue::String("east_coast")
});
Query query = citiesRef.WhereIn(new FieldPath("regions"), new List<string>{"west_coast", "east_coast"});
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 !=
.
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));
const q1 = citiesRef.where("state", "==", "CO").where("name", "==", "Denver");
const q2 = citiesRef.where("state", "==", "CA").where("population", "<", 1000000);
citiesRef
.whereField("state", isEqualTo: "CO")
.whereField("name", isEqualTo: "Denver")
citiesRef
.whereField("state", isEqualTo: "CA")
.whereField("population", isLessThan: 1000000)
[[citiesRef queryWhereField:@"state" isEqualTo:@"CO"]
queryWhereField:@"name" isGreaterThanOrEqualTo:@"Denver"];
[[citiesRef queryWhereField:@"state" isEqualTo:@"CA"]
queryWhereField:@"population" isLessThan:@1000000];
citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver")
citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000)
citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver");
citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000);
final citiesRef = db.collection("cities");
citiesRef
.where("state", isEqualTo: "CO")
.where("name", isEqualTo: "Denver");
citiesRef
.where("state", isEqualTo: "CA")
.where("population", isLessThan: 1000000);
cities_ref.WhereEqualTo("state", FieldValue::String("CO"))
.WhereEqualTo("name", FieldValue::String("Denver"));
cities_ref.WhereEqualTo("state", FieldValue::String("CA"))
.WhereLessThan("population", FieldValue::Integer(1000000));
Query chainedQuery = citiesRef
.WhereEqualTo("State", "CA")
.WhereEqualTo("Name", "San Francisco");
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
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));
const q1 = citiesRef.where("state", ">=", "CA").where("state", "<=", "IN");
const q2 = citiesRef.where("state", "==", "CA").where("population", ">", 1000000);
citiesRef
.whereField("state", isGreaterThanOrEqualTo: "CA")
.whereField("state", isLessThanOrEqualTo: "IN")
citiesRef
.whereField("state", isEqualTo: "CA")
.whereField("population", isGreaterThan: 1000000)
[[citiesRef queryWhereField:@"state" isGreaterThanOrEqualTo:@"CA"]
queryWhereField:@"state" isLessThanOrEqualTo:@"IN"];
[[citiesRef queryWhereField:@"state" isEqualTo:@"CA"]
queryWhereField:@"population" isGreaterThan:@1000000];
citiesRef.whereGreaterThanOrEqualTo("state", "CA")
.whereLessThanOrEqualTo("state", "IN")
citiesRef.whereEqualTo("state", "CA")
.whereGreaterThan("population", 1000000)
citiesRef.whereGreaterThanOrEqualTo("state", "CA")
.whereLessThanOrEqualTo("state", "IN");
citiesRef.whereEqualTo("state", "CA")
.whereGreaterThan("population", 1000000);
final citiesRef = db.collection("cities");
citiesRef
.where("state", isGreaterThanOrEqualTo: "CA")
.where("state", isLessThanOrEqualTo: "IN");
citiesRef
.where("state", isEqualTo: "CA")
.where("population", isGreaterThan: 1000000);
cities_ref.WhereGreaterThanOrEqualTo("state", FieldValue::String("CA"))
.WhereLessThanOrEqualTo("state", FieldValue::String("IN"));
cities_ref.WhereEqualTo("state", FieldValue::String("CA"))
.WhereGreaterThan("population", FieldValue::Integer(1000000));
Query rangeQuery = citiesRef
.WhereGreaterThanOrEqualTo("State", "CA")
.WhereLessThanOrEqualTo("State", "IN");
Inválido : filtros de intervalo em campos diferentes
import { query, where } from "firebase/firestore";
const q = query(citiesRef, where("state", ">=", "CA"), where("population", ">", 100000));
citiesRef.where("state", ">=", "CA").where("population", ">", 100000);
citiesRef
.whereField("state", isGreaterThanOrEqualTo: "CA")
.whereField("population", isGreaterThan: 1000000)
[[citiesRef queryWhereField:@"state" isGreaterThanOrEqualTo:@"CA"]
queryWhereField:@"population" isGreaterThan:@1000000];
citiesRef.whereGreaterThanOrEqualTo("state", "CA")
.whereGreaterThan("population", 100000)
citiesRef.whereGreaterThanOrEqualTo("state", "CA").whereGreaterThan("population", 100000);
final citiesRef = db.collection("cities");
citiesRef
.where("state", isGreaterThanOrEqualTo: "CA")
.where("population", isGreaterThan: 1000000);
// BAD EXAMPLE -- will crash the program:
cities_ref.WhereGreaterThanOrEqualTo("state", FieldValue::String("CA"))
.WhereGreaterThan("population", FieldValue::Integer(100000));
Query invalidRangeQuery = citiesRef
.WhereGreaterThanOrEqualTo("State", "CA")
.WhereGreaterThan("Population", 1000000);
OR
consultas
Você pode combinar restrições com um OR
lógico. Por exemplo:
const q = query(citiesRef,
or(where('capital', '==', true),
where('population', '>=', 1000000)
)
);
Não disponível.
let query = db.collection("cities").whereFilter(Filter.orFilter([
Filter.whereField("capital", isEqualTo: true),
Filter.whereField("population", isGreaterThanOrEqualTo: 1000000);
]))
FIRCollectionReference *collection = [self.db collectionWithPath:@"cities"];
FIRQuery *query = [collection queryWhereFilter:[FIRFilter orFilterWithFilters:@[
[FIRFilter filterWhereField:@"capital" isEqualTo:@YES],
[FIRFilter filterWhereField:@"population" isGreaterThanOrEqualTo:@1000000]
]]];
val query = collection.where(Filter.or(
Filter.equalTo("capital", true),
Filter.greaterThanOrEqualTo("population", 1000000)
))
Query query = collection.where(Filter.or(
Filter.equalTo("capital", true),
Filter.greaterThanOrEqualTo("population", 1000000)
));
var query = db.collection("cities")
.where(
Filter.or(
Filter("capital", isEqualTo: true),
Filter("population", isGreaterThan: 1000000)
));
Trecho não disponível.
Trecho não disponível.
Trecho não disponível.
const bigCities = await citiesRef
.where(
Filter.or(
Filter.where('capital', '==', true),
Filter.where('population', '>=', 1000000)
)
)
.get();
Trecho não disponível.
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));
}
});
Trecho não disponível.
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:
const q = query(collection(db, "cities"), and(
where('state', '==', 'CA'),
or(
where('capital', '==', true),
where('population', '>=', 1000000)
)
));
Não disponível.
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);
])
]))
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]
]]
]]];
val query = collection.where(Filter.and(
Filter.equalTo("state", "CA"),
Filter.or(
Filter.equalTo("capital", true),
Filter.greaterThanOrEqualTo("population", 1000000)
)
))
Query query = collection.where(Filter.and(
Filter.equalTo("state", "CA"),
Filter.or(
Filter.equalTo("capital", true),
Filter.greaterThanOrEqualTo("population", 1000000)
)
));
var query = db.collection("cities")
.where(
Filter.and(
Filter("state", isEqualTo: "CA"),
Filter.or(
Filter("capital", isEqualTo: true),
Filter("population", isGreaterThan: 1000000)
)));
Trecho não disponível.
Trecho não disponível.
Trecho não disponível.
Trecho não disponível.
const bigCitiesInCalifornia = await citiesRef
.where('state', '==', 'CA')
.where(
Filter.or(
Filter.where('capital', '==', true),
Filter.where('population', '>=', 1000000)
)
)
.get();
Trecho não disponível.
Trecho não disponível.
Query query = citiesRef.Where(Filter.And(
Filter.EqualTo("state", "CA"),
Filter.Or(
Filter.EqualTo("capital", true),
Filter.GreaterThanOrEqualTo("population", 1000000)
)
));
Trecho não disponível.
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:
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'
})
]);
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'
})
]);
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)
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];
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)
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);
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);
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;
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:
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());
});
var museums = db.collectionGroup('landmarks').where('type', '==', 'museum');
museums.get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(doc.id, ' => ', doc.data());
});
});
db.collectionGroup("landmarks").whereField("type", isEqualTo: "museum").getDocuments { (snapshot, error) in
// ...
}
[[[self.db collectionGroupWithID:@"landmarks"] queryWhereField:@"type" isEqualTo:@"museum"]
getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) {
// ...
}];
db.collectionGroup("landmarks").whereEqualTo("type", "museum").get()
.addOnSuccessListener { queryDocumentSnapshots ->
// ...
}
db.collectionGroup("landmarks").whereEqualTo("type", "museum").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
// ...
}
});
db
.collectionGroup("landmarks")
.where("type", isEqualTo: "museum")
.get()
.then(
(res) => print("Successfully completed"),
onError: (e) => print("Error completing: $e"),
);
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));
}
});
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, | 4 |
query(collectionRef, | 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, | 50 Esta consulta retorna um erro, pois ultrapassa o limite de 30 disjunções. |
query(collectionRef, | 20 |
query(collectionRef, | 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.
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.
db.collection(“cities”).where(or(“country”, USA”), greaterThan(“population”, 250000));
A consulta acima inclui uma ordem implícita na desigualdade e é equivalente ao seguinte:
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 .