在 Cloud Firestore 中执行简单查询和复合查询

Cloud Firestore 提供了强大的查询功能,用于指定您要从集合或集合组中检索哪些文档。这些查询也可以与 get()addSnapshotListener() 结合使用,如获取数据获取实时更新中所述。

示例数据

首先,请编写一些关于城市的数据,以便我们确定读回这些数据的不同方式:

Web

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

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"] });
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
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"] ])
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
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

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
CollectionReference cities = db.collection("cities"); List<ApiFuture<WriteResult>> futures = new ArrayList<>(); futures.add(     cities         .document("SF")         .set(             new City(                 "San Francisco",                 "CA",                 "USA",                 false,                 860000L,                 Arrays.asList("west_coast", "norcal")))); futures.add(     cities         .document("LA")         .set(             new City(                 "Los Angeles",                 "CA",                 "USA",                 false,                 3900000L,                 Arrays.asList("west_coast", "socal")))); futures.add(     cities         .document("DC")         .set(             new City(                 "Washington D.C.", null, "USA", true, 680000L, Arrays.asList("east_coast")))); futures.add(     cities         .document("TOK")         .set(             new City(                 "Tokyo", null, "Japan", true, 9000000L, Arrays.asList("kanto", "honshu")))); futures.add(     cities         .document("BJ")         .set(             new City(                 "Beijing",                 null,                 "China",                 true,                 21500000L,                 Arrays.asList("jingjinji", "hebei")))); // (optional) block on documents successfully added ApiFutures.allAsList(futures).get();
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") 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
const citiesRef = db.collection('cities');  await citiesRef.doc('SF').set({   name: 'San Francisco', state: 'CA', country: 'USA',   capital: false, population: 860000,   regions: ['west_coast', 'norcal'] }); await citiesRef.doc('LA').set({   name: 'Los Angeles', state: 'CA', country: 'USA',   capital: false, population: 3900000,   regions: ['west_coast', 'socal'] }); await citiesRef.doc('DC').set({   name: 'Washington, D.C.', state: null, country: 'USA',   capital: true, population: 680000,   regions: ['east_coast'] }); await citiesRef.doc('TOK').set({   name: 'Tokyo', state: null, country: 'Japan',   capital: true, population: 9000000,   regions: ['kanto', 'honshu'] }); await citiesRef.doc('BJ').set({   name: 'Beijing', state: null, country: 'China',   capital: true, population: 21500000,   regions: ['jingjinji', 'hebei'] });
Go
cities := []struct { 	id string 	c  City }{ 	{ 		id: "SF", 		c: City{Name: "San Francisco", State: "CA", Country: "USA", 			Capital: false, Population: 860000, 			Regions: []string{"west_coast", "norcal"}}, 	}, 	{ 		id: "LA", 		c: City{Name: "Los Angeles", State: "CA", Country: "USA", 			Capital: false, Population: 3900000, 			Regions: []string{"west_coast", "socal"}}, 	}, 	{ 		id: "DC", 		c: City{Name: "Washington D.C.", Country: "USA", 			Capital: true, Population: 680000, 			Regions: []string{"east_coast"}}, 	}, 	{ 		id: "TOK", 		c: City{Name: "Tokyo", Country: "Japan", 			Capital: true, Population: 9000000, 			Regions: []string{"kanto", "honshu"}}, 	}, 	{ 		id: "BJ", 		c: City{Name: "Beijing", Country: "China", 			Capital: true, Population: 21500000, 			Regions: []string{"jingjinji", "hebei"}}, 	}, } for _, c := range cities { 	if _, err := client.Collection("cities").Doc(c.id).Set(ctx, c.c); err != nil { 		return err 	} }
PHP
$citiesRef = $db->collection('samples/php/cities'); $citiesRef->document('SF')->set([     'name' => 'San Francisco',     'state' => 'CA',     'country' => 'USA',     'capital' => false,     'population' => 860000,     'density' => 18000,     'regions' => ['west_coast', 'norcal'] ]); $citiesRef->document('LA')->set([     'name' => 'Los Angeles',     'state' => 'CA',     'country' => 'USA',     'capital' => false,     'population' => 3900000,     'density' => 8000,     'regions' => ['west_coast', 'socal'] ]); $citiesRef->document('DC')->set([     'name' => 'Washington D.C.',     'state' => null,     'country' => 'USA',     'capital' => true,     'population' => 680000,     'density' => 11000,     'regions' => ['east_coast'] ]); $citiesRef->document('TOK')->set([     'name' => 'Tokyo',     'state' => null,     'country' => 'Japan',     'capital' => true,     'population' => 9000000,     'density' => 16000,     'regions' => ['kanto', 'honshu'] ]); $citiesRef->document('BJ')->set([     'name' => 'Beijing',     'state' => null,     'country' => 'China',     'capital' => true,     'population' => 21500000,     'density' => 3500,     'regions' => ['jingjinji', 'hebei'] ]); printf('Added example cities data to the cities collection.' . PHP_EOL);
Unity
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#
CollectionReference citiesRef = db.Collection("cities"); await citiesRef.Document("SF").SetAsync(new Dictionary<string, object> {     { "Name", "San Francisco" },     { "State", "CA" },     { "Country", "USA" },     { "Capital", false },     { "Population", 860000 },     { "Density", 18000 },     { "Regions", new[] {"west_coast", "norcal"} } }); await citiesRef.Document("LA").SetAsync(new Dictionary<string, object> {     { "Name", "Los Angeles" },     { "State", "CA" },     { "Country", "USA" },     { "Capital", false },     { "Population", 3900000 },     { "Density", 8300 },     { "Regions", new[] {"west_coast", "socal"} } }); await citiesRef.Document("DC").SetAsync(new Dictionary<string, object> {     { "Name", "Washington D.C." },     { "State", null },     { "Country", "USA" },     { "Capital", true },     { "Population", 680000 },     { "Density", 11300 },     { "Regions", new[] {"east_coast"} } }); await citiesRef.Document("TOK").SetAsync(new Dictionary<string, object> {     { "Name", "Tokyo" },     { "State", null },     { "Country", "Japan" },     { "Capital", true },     { "Population", 9000000 },     { "Density", 16000 },     { "Regions", new[] {"kanto", "honshu"} } }); await citiesRef.Document("BJ").SetAsync(new Dictionary<string, object> {     { "Name", "Beijing" },     { "State", null },     { "Country", "China" },     { "Capital", true },     { "Population", 21500000 },     { "Density", 3500 },     { "Regions", new[] {"jingjinji", "hebei"} } }); Console.WriteLine("Added example cities data to the cities collection.");
Ruby
cities_ref = firestore.col collection_path cities_ref.doc("SF").set(   {     name:       "San Francisco",     state:      "CA",     country:    "USA",     capital:    false,     density:    18_000,     population: 860_000,     regions:    ["west_coast", "norcal"]   } ) cities_ref.doc("LA").set(   {     name:       "Los Angeles",     state:      "CA",     country:    "USA",     capital:    false,     density:    8_300,     population: 3_900_000,     regions:    ["west_coast", "socal"]   } ) cities_ref.doc("DC").set(   {     name:       "Washington D.C.",     state:      nil,     country:    "USA",     capital:    true,     density:    11_300,     population: 680_000,     regions:    ["east_coast"]   } ) cities_ref.doc("TOK").set(   {     name:       "Tokyo",     state:      nil,     country:    "Japan",     capital:    true,     density:    16_000,     population: 9_000_000,     regions:    ["kanto", "honshu"]   } ) cities_ref.doc("BJ").set(   {     name:       "Beijing",     state:      nil,     country:    "China",     capital:    true,     density:    3_500,     population: 21_500_000,     regions:    ["jingjinji", "hebei"]   } )

简单查询

以下查询会返回 CA 州的所有城市:

Web

// 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

// Create a reference to the cities collection var citiesRef = db.collection("cities");  // Create a query against the collection. var query = citiesRef.where("state", "==", "CA");
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
// 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")
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
// 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

// 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
// Create a reference to the cities collection CollectionReference cities = db.collection("cities"); // Create a query against the collection. Query query = cities.whereEqualTo("state", "CA"); // retrieve  query results asynchronously using query.get() ApiFuture<QuerySnapshot> querySnapshot = query.get();  for (DocumentSnapshot document : querySnapshot.get().getDocuments()) {   System.out.println(document.getId()); }
Python
# Create a reference to the cities collection cities_ref = db.collection("cities")  # Create a query against the collection query_ref = cities_ref.where(filter=FieldFilter("state", "==", "CA"))

Python

# Create a reference to the cities collection cities_ref = db.collection("cities")  # Create a query against the collection query_ref = cities_ref.where(filter=FieldFilter("state", "==", "CA"))
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
// Create a reference to the cities collection const citiesRef = db.collection('cities');  // Create a query against the collection const queryRef = citiesRef.where('state', '==', 'CA');
Go
query := client.Collection("cities").Where("state", "==", "CA")
PHP
$citiesRef = $db->collection('samples/php/cities'); $query = $citiesRef->where('state', '=', 'CA'); $snapshot = $query->documents(); foreach ($snapshot as $document) {     printf('Document %s returned by query state=CA' . PHP_EOL, $document->id()); }
Unity
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#
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereEqualTo("State", "CA"); QuerySnapshot querySnapshot = await query.GetSnapshotAsync(); foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents) {     Console.WriteLine("Document {0} returned by query State=CA", documentSnapshot.Id); }
Ruby
cities_ref = firestore.col collection_path  query = cities_ref.where "state", "=", "CA"  query.get do |city|   puts "Document #{city.document_id} returned by query state=CA." end

以下查询会返回所有首府城市:

Web

import { collection, query, where } from "firebase/firestore"; const citiesRef = collection(db, "cities");  const q = query(citiesRef, where("capital", "==", true));

Web

var citiesRef = db.collection("cities");  var query = citiesRef.where("capital", "==", true);
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
let capitalCities = db.collection("cities").whereField("capital", isEqualTo: true)
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
FIRQuery *capitalCities =     [[self.db collectionWithPath:@"cities"] queryWhereField:@"capital" isEqualTo:@YES];

Kotlin

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
// Create a reference to the cities collection CollectionReference cities = db.collection("cities"); // Create a query against the collection. Query query = cities.whereEqualTo("capital", true); // retrieve  query results asynchronously using query.get() ApiFuture<QuerySnapshot> querySnapshot = query.get();  for (DocumentSnapshot document : querySnapshot.get().getDocuments()) {   System.out.println(document.getId()); }
Python
cities_ref = db.collection("cities")  query = cities_ref.where(filter=FieldFilter("capital", "==", True))

Python

cities_ref = db.collection("cities")  query = cities_ref.where(filter=FieldFilter("capital", "==", True))
C++
Query capital_cities = db->Collection("cities").WhereEqualTo(     "capital", FieldValue::Boolean(true));
Node.js
// Create a reference to the cities collection const citiesRef = db.collection('cities');  // Create a query against the collection const allCapitalsRes = citiesRef.where('capital', '==', true);
Go
query := client.Collection("cities").Where("capital", "==", true)
PHP
$citiesRef = $db->collection('samples/php/cities'); $query = $citiesRef->where('capital', '=', true); $snapshot = $query->documents(); foreach ($snapshot as $document) {     printf('Document %s returned by query capital=true' . PHP_EOL, $document->id()); }
Unity
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#
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereEqualTo("Capital", true); QuerySnapshot querySnapshot = await query.GetSnapshotAsync(); foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents) {     Console.WriteLine("Document {0} returned by query Capital=true", documentSnapshot.Id); }
Ruby
cities_ref = firestore.col collection_path  query = cities_ref.where "capital", "=", true  query.get do |city|   puts "Document #{city.document_id} returned by query capital=true." end

执行查询

创建查询对象后,使用 get() 函数检索结果:

Web

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

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);     });
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
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)") }
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
[[[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

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
// asynchronously retrieve multiple documents ApiFuture<QuerySnapshot> future = db.collection("cities").whereEqualTo("capital", true).get(); // future.get() blocks on response List<QueryDocumentSnapshot> documents = future.get().getDocuments(); for (DocumentSnapshot document : documents) {   System.out.println(document.getId() + " => " + document.toObject(City.class)); }
Python
# Note: Use of CollectionRef stream() is prefered to get() docs = (     db.collection("cities")     .where(filter=FieldFilter("capital", "==", True))     .stream() )  for doc in docs:     print(f"{doc.id} => {doc.to_dict()}")

Python

# Note: Use of CollectionRef stream() is prefered to get() docs = (     db.collection("cities")     .where(filter=FieldFilter("capital", "==", True))     .stream() )  async for doc in docs:     print(f"{doc.id} => {doc.to_dict()}")
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
const citiesRef = db.collection('cities'); const snapshot = await citiesRef.where('capital', '==', true).get(); if (snapshot.empty) {   console.log('No matching documents.');   return; }    snapshot.forEach(doc => {   console.log(doc.id, '=>', doc.data()); });
Go
 import ( 	"context" 	"fmt"  	"cloud.google.com/go/firestore" 	"google.golang.org/api/iterator" )  func multipleDocs(ctx context.Context, client *firestore.Client) error { 	fmt.Println("All capital cities:") 	iter := client.Collection("cities").Where("capital", "==", true).Documents(ctx) 	for { 		doc, err := iter.Next() 		if err == iterator.Done { 			break 		} 		if err != nil { 			return err 		} 		fmt.Println(doc.Data()) 	} 	return nil } 
PHP

PHP

如需详细了解如何安装和创建 Cloud Firestore 客户端,请参阅 Cloud Firestore 客户端库

$citiesRef = $db->collection('samples/php/cities'); $query = $citiesRef->where('capital', '=', true); $documents = $query->documents(); foreach ($documents as $document) {     if ($document->exists()) {         printf('Document data for document %s:' . PHP_EOL, $document->id());         print_r($document->data());         printf(PHP_EOL);     } else {         printf('Document %s does not exist!' . PHP_EOL, $document->id());     } }
Unity
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#
Query capitalQuery = db.Collection("cities").WhereEqualTo("Capital", true); QuerySnapshot capitalQuerySnapshot = await capitalQuery.GetSnapshotAsync(); foreach (DocumentSnapshot documentSnapshot in capitalQuerySnapshot.Documents) {     Console.WriteLine("Document data for {0} document:", documentSnapshot.Id);     Dictionary<string, object> city = documentSnapshot.ToDictionary();     foreach (KeyValuePair<string, object> pair in city)     {         Console.WriteLine("{0}: {1}", pair.Key, pair.Value);     }     Console.WriteLine(""); }
Ruby
cities_ref = firestore.col collection_path  query = cities_ref.where "capital", "=", true  query.get do |city|   puts "#{city.document_id} data: #{city.data}." end

如需详细了解如何检索查询结果,请参阅获取数据。您还可以向查询中添加监听器,以获取当前结果并监听以后的更新。

查询运算符

where() 方法接受三个参数:作为过滤依据的字段、比较运算符和值。Cloud Firestore 支持以下比较运算符:

例如:

Web

const stateQuery = query(citiesRef, where("state", "==", "CA")); const populationQuery = query(citiesRef, where("population", "<", 100000)); const nameQuery = query(citiesRef, where("name", ">=", "San Francisco"));

Web

const stateQuery = citiesRef.where("state", "==", "CA"); const populationQuery = citiesRef.where("population", "<", 100000); const nameQuery = citiesRef.where("name", ">=", "San Francisco");
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
let stateQuery = citiesRef.whereField("state", isEqualTo: "CA") let populationQuery = citiesRef.whereField("population", isLessThan: 100000) let nameQuery = citiesRef.whereField("name", isGreaterThanOrEqualTo: "San Francisco")
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
FIRQuery *stateQuery = [citiesRef queryWhereField:@"state" isEqualTo:@"CA"]; FIRQuery *populationQuery = [citiesRef queryWhereField:@"population" isLessThan:@100000]; FIRQuery *nameQuery = [citiesRef queryWhereField:@"name" isGreaterThanOrEqualTo:@"San Francisco"];

Kotlin

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
Query stateQuery = cities.whereEqualTo("state", "CA"); Query populationQuery = cities.whereLessThan("population", 1000000L); Query nameQuery = cities.whereGreaterThanOrEqualTo("name", "San Francisco");
Python
cities_ref = db.collection("cities")  cities_ref.where(filter=FieldFilter("state", "==", "CA")) cities_ref.where(filter=FieldFilter("population", "<", 1000000)) cities_ref.where(filter=FieldFilter("name", ">=", "San Francisco"))

Python

cities_ref = db.collection("cities")  cities_ref.where(filter=FieldFilter("state", "==", "CA")) cities_ref.where(filter=FieldFilter("population", "<", 1000000)) cities_ref.where(filter=FieldFilter("name", ">=", "San Francisco"))
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
const stateQueryRes = await citiesRef.where('state', '==', 'CA').get(); const populationQueryRes = await citiesRef.where('population', '<', 1000000).get(); const nameQueryRes = await citiesRef.where('name', '>=', 'San Francisco').get();
Go
countryQuery := cities.Where("state", "==", "CA") popQuery := cities.Where("population", "<", 1000000) cityQuery := cities.Where("name", ">=", "San Francisco")
PHP
$stateQuery = $citiesRef->where('state', '=', 'CA'); $populationQuery = $citiesRef->where('population', '>', 1000000); $nameQuery = $citiesRef->where('name', '>=', 'San Francisco');
Unity
Query stateQuery = citiesRef.WhereEqualTo("State", "CA"); Query populationQuery = citiesRef.WhereGreaterThan("Population", 1000000); Query nameQuery = citiesRef.WhereGreaterThanOrEqualTo("Name", "San Francisco");
C#
CollectionReference citiesRef = db.Collection("cities"); Query stateQuery = citiesRef.WhereEqualTo("State", "CA"); Query populationQuery = citiesRef.WhereGreaterThan("Population", 1000000); Query nameQuery = citiesRef.WhereGreaterThanOrEqualTo("Name", "San Francisco");
Ruby
state_query      = cities_ref.where "state", "=", "CA" population_query = cities_ref.where "population", ">", 1_000_000 name_query       = cities_ref.where "name", ">=", "San Francisco"

不等于 (!=)

使用不等于 (!=) 运算符会返回给定字段存在但与比较值不匹配的文档。例如:

Web

const notCapitalQuery = query(citiesRef, where("capital", "!=", false));

Web

citiesRef.where("capital", "!=", false);
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
let notEqualQuery = citiesRef.whereField("capital", isNotEqualTo: false)
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
query = [citiesRef queryWhereField:@"capital" isNotEqualTo:@NO];

Kotlin

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
CollectionReference citiesRef = db.collection("cities");  Query query = citiesRef.whereNotEqualTo("capital", false);
Python
// Snippet not yet available
C++
cities_ref.WhereNotEqualTo("capital", FieldValue::Boolean(false));
Node.js
const capitalNotFalseRes = await citiesRef.where('capital', '!=', false).get();
Go
// Snippet not yet available
PHP
$stateQuery = $citiesRef->where('capital', '!=', false);
Unity
Query query = citiesRef.WhereNotEqualTo("capital", false); Query query = citiesRef.WhereNotEqualTo("capital", false);
C#
// Snippet not yet available
Ruby
cities_ref = firestore.col collection_path query = cities_ref.where "capital", "!=", false

此查询会返回每一个存在 capital 字段但其值不是 falsenullcity 文档。这包括 capital 字段值等于 true 或者任何 null 以外的非布尔值的 city 文档。

此查询不会返回 capital 字段不存在的 city 文档。不等于 (!=) 和 not-in 查询会排除给定字段不存在的文档

字段只要设置了值即会存在,这些值包括空字符串 ("")、nullNaN(非数字)。请注意,null 字段值与 != 子句不匹配,因为 x != null 求值为 undefined

限制

请注意 != 查询的以下限制:

  • 只有给定字段存在的文档才能与该查询匹配。
  • 您不能在复合查询中组合使用 not-in!=

数组成员

您可以使用 array-contains 运算符根据数组值进行过滤。例如:

Web

import { query, where } from "firebase/firestore";   const q = query(citiesRef, where("regions", "array-contains", "west_coast"));

Web

citiesRef.where("regions", "array-contains", "west_coast");
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
citiesRef   .whereField("regions", arrayContains: "west_coast")
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
[citiesRef queryWhereField:@"state" arrayContains:@"west_coast"];

Kotlin

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
CollectionReference citiesRef = db.collection("cities"); Query westCoastQuery = citiesRef.whereArrayContains("regions", "west_coast");
Python
cities_ref = db.collection("cities")  query = cities_ref.where(     filter=FieldFilter("regions", "array_contains", "west_coast") )

Python

cities_ref = db.collection("cities")  query = cities_ref.where(     filter=FieldFilter("regions", "array_contains", "west_coast") )
C++
CollectionReference cities_ref = db->Collection("cities");  cities_ref.WhereArrayContains("region", FieldValue::String("west_coast"));
Node.js
const westCoastCities = citiesRef.where('regions', 'array-contains',   'west_coast').get();
Go
query := cities.Where("regions", "array-contains", "west_coast").Documents(ctx)
PHP
$containsQuery = $citiesRef->where('regions', 'array-contains', 'west_coast');
Unity
CollectionReference citiesRef = db.Collection("cities"); Query arrayContainsQuery = citiesRef.WhereArrayContains("region", "west_coast");
C#
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereArrayContains("Regions", "west_coast");
Ruby
cities_ref = firestore.col collection_path cities = cities_ref.where "regions", "array-contains", "west_coast"

此查询会返回每一个 regions 字段是包含 west_coast 的数组的 city 文档。对于您查询的值,如果数组具有该值的多个实例,结果将仅包含该文档一次。

每个析取运算(or 组)最多只能使用一个 array-contains 子句。不能在同一析取运算中将 array-containsarray-contains-any 组合使用。

innot-inarray-contains-any

使用 in 运算符可通过逻辑 OR 在同一字段上结合使用最多 30 个等式 (==) 子句。in 查询会返回给定字段与任意比较值匹配的文档。例如:

Web

import { query, where } from "firebase/firestore";  const q = query(citiesRef, where('country', 'in', ['USA', 'Japan']));

Web

citiesRef.where('country', 'in', ['USA', 'Japan']);
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
let citiesRef = db.collection("cities")  citiesRef.whereField("country", in: ["USA", "Japan"])
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"];  [citiesRef queryWhereField:@"country" in:@[@"USA", @"Japan"]];

Kotlin

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
CollectionReference citiesRef = db.collection("cities");  Query query = citiesRef.whereIn("country", Arrays.asList("USA", "Japan"));
Python
cities_ref = db.collection("cities")  query = cities_ref.where(filter=FieldFilter("country", "in", ["USA", "Japan"])) return query

Python

cities_ref = db.collection("cities")  query = cities_ref.where(filter=FieldFilter("country", "in", ["USA", "Japan"])) return query
C++
CollectionReference cities_ref = db->Collection("cities");  cities_ref.WhereIn("country", std::vector<FieldValue> {   FieldValue::String("USA"),   FieldValue::String("Japan") });
Node.js
const usaOrJapan = await citiesRef.where('country', 'in', ['USA', 'Japan']).get();
Go
cities := client.Collection("cities") query := cities.Where("country", "in", []string{"USA", "Japan"}).Documents(ctx)
PHP
$rangeQuery = $citiesRef->where('country', 'in', ['USA', 'Japan']);
Unity
CollectionReference citiesRef = db.Collection("cities"); List countriesList = new List<object>() {"USA", "Japan"};  Query whereInQuery = citiesRef.WhereIn("country", countriesList);
C#
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereIn("Country", new[] { "USA", "Japan" });
Ruby
cities_ref = firestore.col collection_path usr_or_japan = cities_ref.where "country", "in", ["USA", "Japan"]

此查询会返回每一个 country 字段设置为 USAJapancity 文档。根据示例数据,这包括 SFLADCTOK 文档。

not-in

使用 not-in 运算符可通过逻辑 AND 在同一字段上结合使用最多 10 个不等于 (!=) 子句。not-in 查询返回符合以下条件的文档:给定字段存在但不是 null,并且不匹配任何比较值。例如:

Web

import { query, where } from "firebase/firestore";  const q = query(citiesRef, where('country', 'not-in', ['USA', 'Japan']));

Web

citiesRef.where('country', 'not-in', ['USA', 'Japan']);
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
citiesRef.whereField("country", notIn: ["USA", "Japan"])
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
[citiesRef queryWhereField:@"country" notIn:@[@"USA", @"Japan"]];

Kotlin

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
CollectionReference citiesRef = db.collection("cities");  Query query = citiesRef.whereNotIn("country", Arrays.asList("USA", "Japan"));
Python
// Snippet not yet available
C++
cities_ref.WhereNotIn("country", std::vector<FieldValue> {   FieldValue::String("USA"),   FieldValue::String("Japan") });
Node.js
const notUsaOrJapan = await citiesRef.where('country', 'not-in', ['USA', 'Japan']).get();
Go
// Snippet not yet available
PHP
$stateQuery = $citiesRef->where(     'country',     \Google\Cloud\Firestore\V1\StructuredQuery\FieldFilter\Operator::NOT_IN,     ['USA', 'Japan'] );
Unity
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
Ruby
cities_ref = firestore.col collection_path usr_or_japan = cities_ref.where "country", "not_in", ["USA", "Japan"]

此查询会返回每一个 country 字段存在并且未设置为 USAJapannullcity 文档。根据示例数据,这包括 LondonHong Kong 文档。

not-in 查询会排除给定字段不存在的文档。如果一个字段被设置为任何值,包括空字符串 ("")、nullNaN(非数字),则该字段存在。请注意,x != null 的计算结果为 undefined。比较值包括 nullnot-in 查询不匹配任何文档。

array-contains-any

使用 array-contains-any 运算符可通过逻辑 OR 在同一字段上结合使用最多 30 个 array-contains 子句。array-contains-any 查询会返回给定字段是包含一个或多个比较值的数组的文档:

Web

import { query, where } from "firebase/firestore";    const q = query(citiesRef,    where('regions', 'array-contains-any', ['west_coast', 'east_coast']));

Web

citiesRef.where('regions', 'array-contains-any',     ['west_coast', 'east_coast']);
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
let citiesRef = db.collection("cities") citiesRef.whereField("regions", arrayContainsAny: ["west_coast", "east_coast"])
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"];  [citiesRef queryWhereField:@"regions" arrayContainsAny:@[@"west_coast", @"east_coast"]];

Kotlin

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
CollectionReference citiesRef = db.collection("cities");  Query query =     citiesRef.whereArrayContainsAny("regions", Arrays.asList("west_coast", "east_coast"));
Python
cities_ref = db.collection("cities")  query = cities_ref.where(     filter=FieldFilter(         "regions", "array_contains_any", ["west_coast", "east_coast"]     ) ) return query

Python

cities_ref = db.collection("cities")  query = cities_ref.where(     filter=FieldFilter(         "regions", "array_contains_any", ["west_coast", "east_coast"]     ) ) return query
C++
CollectionReference cities_ref = db->Collection("cities");  cities_ref.WhereArrayContainsAny("region", std::vector<FieldValue> {   FieldValue::String("west_coast"),   FieldValue::String("east_coast") });
Node.js
const coastalCities = await citiesRef.where('regions', 'array-contains-any',     ['west_coast', 'east_coast']).get();
Go
cities := client.Collection("cities") query := cities.Where("regions", "array-contains-any", []string{"west_coast", "east_coast"}).Documents(ctx)
PHP
$containsQuery = $citiesRef->where('regions', 'array-contains-any', ['west_coast', 'east_coast']);
Unity
Query query = citiesRef.WhereArrayContainsAny(                          "regions",                          new List<object>()                          {                             new List<object>(){"west_coast"},                             new List<object>(){"east_coast"}});
C#
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereArrayContainsAny("Regions", new[] { "west_coast", "east_coast" });
Ruby
cities_ref = firestore.col collection_path costal_cities = cities_ref.where "regions", "array-contains-any", ["west_coast", "east_coast"]

此查询会返回每一个 regions 字段是包含 west_coasteast_coast 的数组的 city 文档。根据示例数据,这包括 SFLADC 文档。

来自 array-contains-any 的结果会被去重。即使文档的数组字段匹配多个比较值,结果集也仅包含该文档一次。

array-contains-any 始终按数组数据类型进行过滤。例如,上面的查询不会返回 regions 字段不是数组而是字符串 west_coast 的 city 文档。

您可以将数组值用作 in 的比较值,但与 array-contains-any 不同,子句查找的是与数组长度、顺序和值完全匹配的项。例如:

Web

import { query, where } from "firebase/firestore";    const q = query(citiesRef, where('regions', 'in', [['west_coast'], ['east_coast']]));

Web

citiesRef.where('regions', 'in',     [['west_coast'], ['east_coast']]);
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
citiesRef.whereField("regions", in: [["west_coast"], ["east_coast"]])
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
[citiesRef queryWhereField:@"regions" in:@[@[@"west_coast"], @[@"east_coast"]]];

Kotlin

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
CollectionReference citiesRef = db.collection("cities");  Query query =     citiesRef.whereIn(         "regions", Arrays.asList(Arrays.asList("west_coast"), Arrays.asList("east_coast")));
Python
cities_ref = db.collection("cities")  query = cities_ref.where(     filter=FieldFilter("regions", "in", [["west_coast"], ["east_coast"]]) ) return query

Python

cities_ref = db.collection("cities")  query = cities_ref.where(     filter=FieldFilter("regions", "in", [["west_coast"], ["east_coast"]]) ) return query
C++
cities_ref.WhereIn("region", std::vector<FieldValue> {   FieldValue::String("west_coast"),   FieldValue::String("east_coast") });
Node.js
const exactlyOneCoast = await citiesRef.where('regions', 'in',     [['west_coast', 'east_coast']]).get();
Go
cities := client.Collection("cities") query := cities.Where("regions", "in", [][]string{{"west_coast"}, {"east_coast"}}).Documents(ctx)
PHP
$rangeQuery = $citiesRef->where('regions', 'in', [['west_coast'], ['east_coast']]);
Unity
Query query = citiesRef.WhereIn(new FieldPath("regions"), new List<string>{"west_coast", "east_coast"});
C#
CollectionReference citiesRef = db.Collection("cities"); Query query = citiesRef.WhereIn("Regions",     new[] { new[] { "west_coast" }, new[] { "east_coast" } });
Ruby
cities_ref = firestore.col collection_path exactly_one_cost = cities_ref.where "regions", "in", [["west_coast"], ["east_coast"]]

此查询会返回每个 regions 字段是仅包含一个元素(west_coasteast_coast)的数组的 city 文档。在示例数据中,只有 DC 文档符合条件,因为其 regions 字段为 ["east_coast"]。但是,SF 文档不匹配,因为其 regions 字段为 ["west_coast", "norcal"]

限制

请注意 innot-inarray-contains-any 的以下限制:

  • Cloud Firestore 支持通过 orinarray-contains-any 运算符进行逻辑 OR 查询。这些查询最多只能包含 30 个析取运算(基于查询的析取范式)
  • 每个析取运算(or 组)最多只能使用一个 array-contains 子句。不能在同一析取运算中将 array-containsarray-contains-any 组合使用。
  • 不能将 not-in 与不等于 != 子句组合使用。
  • not-in 最多支持 10 个比较值。

复合 (AND) 查询

您可以通过串联多个等式运算符(==array-contains)将约束条件与逻辑 AND 组合使用。不过,若要将等式运算符与不等式运算符 <<=>!= 组合使用,则必须创建复合索引

Web

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

const q1 = citiesRef.where("state", "==", "CO").where("name", "==", "Denver"); const q2 = citiesRef.where("state", "==", "CA").where("population", "<", 1000000);
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
citiesRef   .whereField("state", isEqualTo: "CO")   .whereField("name", isEqualTo: "Denver") citiesRef   .whereField("state", isEqualTo: "CA")   .whereField("population", isLessThan: 1000000)
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
[[citiesRef queryWhereField:@"state" isEqualTo:@"CO"]     queryWhereField:@"name" isGreaterThanOrEqualTo:@"Denver"]; [[citiesRef queryWhereField:@"state" isEqualTo:@"CA"]     queryWhereField:@"population" isLessThan:@1000000];

Kotlin

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
Query chainedQuery1 = cities.whereEqualTo("state", "CO").whereEqualTo("name", "Denver");
Python
cities_ref = db.collection("cities")  denver_query = cities_ref.where(filter=FieldFilter("state", "==", "CO")).where(     filter=FieldFilter("name", "==", "Denver") ) large_us_cities_query = cities_ref.where(     filter=FieldFilter("state", "==", "CA") ).where(filter=FieldFilter("population", ">", 1000000))

Python

cities_ref = db.collection("cities")  denver_query = cities_ref.where(filter=FieldFilter("state", "==", "CO")).where(     filter=FieldFilter("name", "==", "Denver") ) large_us_cities_query = cities_ref.where(     filter=FieldFilter("state", "==", "CA") ).where(filter=FieldFilter("population", ">", 1000000))
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
citiesRef.where('state', '==', 'CO').where('name', '==', 'Denver'); citiesRef.where('state', '==', 'CA').where('population', '<', 1000000);
Go
denverQuery := cities.Where("name", "==", "Denver").Where("state", "==", "CO") caliQuery := cities.Where("state", "==", "CA").Where("population", "<=", 1000000) query := cities.Where("country", "==", "USA").Where("population", ">", 5000000)
PHP
$chainedQuery = $citiesRef     ->where('state', '=', 'CA')     ->where('name', '=', 'San Francisco');
Unity
Query chainedQuery = citiesRef     .WhereEqualTo("State", "CA")     .WhereEqualTo("Name", "San Francisco");
C#
CollectionReference citiesRef = db.Collection("cities"); Query chainedQuery = citiesRef     .WhereEqualTo("State", "CA")     .WhereEqualTo("Name", "San Francisco");
Ruby
chained_query = cities_ref.where("state", "=", "CA").where("name", "=", "San Francisco")

OR 个查询

您可以将限制条件与逻辑 OR 组合使用。例如:

Web

const q = query(citiesRef,   or(where('capital', '==', true),      where('population', '>=', 1000000)   ) );   

Web

不可用。

Swift
let query = db.collection("cities").whereFilter(Filter.orFilter([                 Filter.whereField("capital", isEqualTo: true),                 Filter.whereField("population", isGreaterThanOrEqualTo: 1000000);             ]))   
Objective-C
  FIRCollectionReference *collection = [self.db collectionWithPath:@"cities"];   FIRQuery *query = [collection queryWhereFilter:[FIRFilter orFilterWithFilters:@[       [FIRFilter filterWhereField:@"capital" isEqualTo:@YES],       [FIRFilter filterWhereField:@"population" isGreaterThanOrEqualTo:@1000000]   ]]];   

Kotlin

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

无可用代码段。

Python
from google.cloud.firestore_v1.base_query import FieldFilter, Or  col_ref = client.collection("cities") # Execute the query query = col_ref.where(     filter=Or(         [             FieldFilter("capital", "==", True),             FieldFilter("population", ">", 1_000_000),         ]     ) ) docs = query.stream()

Python

无可用代码段。

C++

无可用代码段。

Node.js
const bigCities = await citiesRef   .where(     Filter.or(       Filter.where('capital', '==', true),       Filter.where('population', '>=', 1000000)     )   )   .get();
Go
import ( 	"context" 	"fmt" 	"io"  	firestore "cloud.google.com/go/firestore" 	"google.golang.org/api/iterator" )  func queryFilterOr(w io.Writer, projectId string) error { 	// Instantiate a client 	ctx := context.Background() 	client, err := firestore.NewClient(ctx, projectId) 	if err != nil { 		return err 	} 	// always be sure to close the client to release resources 	defer client.Close()  	q1 := firestore.PropertyFilter{ 		Path:     "birthYear", 		Operator: "==", 		Value:    1906, 	}  	q2 := firestore.PropertyFilter{ 		Path:     "birthYear", 		Operator: "==", 		Value:    1815, 	}  	orFilter := firestore.OrFilter{ 		Filters: []firestore.EntityFilter{q1, q2}, 	}  	orQuery := client.Collection("users").WhereEntity(orFilter) 	it := orQuery.Documents(ctx) 	if err != nil { 		return err 	}  	fmt.Fprint(w, "Individual documents:\n") 	for { 		doc, err := it.Next() 		if err == iterator.Done { 			break 		} 		if err != nil { 			return fmt.Errorf("documents iterator: %w", err) 		} 		fmt.Fprintf(w, "%s: %s", doc.Ref.ID, doc.Data()["birthYear"]) 	}  	return nil } 
PHP

无可用代码段。

Unity
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#

无可用代码段。

Ruby

无可用代码段。

Cloud Firestore 使用复合索引来处理 OR 查询。如果您的索引不支持该查询,Cloud Firestore为您的数据库建议其他索引

您可以将 OR 查询与复合查询组合使用,按 ORAND 运算的组合结果进行过滤。例如:

Web

const q = query(collection(db, "cities"), and(   where('state', '==', 'CA'),      or(     where('capital', '==', true),     where('population', '>=', 1000000)   ) ));

Web

不可用。

Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
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)   ]) ]))
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
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

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

无可用代码段。

Python

无可用代码段。

Python

无可用代码段。

C++

无可用代码段。

Node.js
const bigCitiesInCalifornia = await citiesRef   .where('state', '==', 'CA')   .where(     Filter.or(       Filter.where('capital', '==', true),       Filter.where('population', '>=', 1000000)     )   )   .get();
Go

无可用代码段。

PHP

无可用代码段。

Unity
Query query = citiesRef.Where(Filter.And(     Filter.EqualTo("state", "CA"),     Filter.Or(         Filter.EqualTo("capital", true),         Filter.GreaterThanOrEqualTo("population", 1000000)     ) ));
C#

无可用代码段。

Ruby

无可用代码段。

限制

请注意 or 查询的以下限制:

如需了解有关限制的完整说明,请参阅查询限制

集合组查询

集合组由具有相同 ID 的所有集合组成。默认情况下,查询从数据库的单个集合中检索结果。您可以使用集合组查询从集合组(而不是从单个集合)中检索文档。

例如,您可以通过向每个城市添加地标子集来创建 landmarks 集合组:

Web

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

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'     }) ]);
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
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)
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
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

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
CollectionReference cities = db.collection("cities");  final List<ApiFuture<WriteResult>> futures =     Arrays.asList(         cities             .document("SF")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "Golden Gate Bridge");                     put("type", "bridge");                   }                 }),         cities             .document("SF")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "Legion of Honor");                     put("type", "museum");                   }                 }),         cities             .document("LA")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "Griffith Park");                     put("type", "park");                   }                 }),         cities             .document("LA")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "The Getty");                     put("type", "museum");                   }                 }),         cities             .document("DC")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "Lincoln Memorial");                     put("type", "memorial");                   }                 }),         cities             .document("DC")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "National Air and Space Museum");                     put("type", "museum");                   }                 }),         cities             .document("TOK")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "Ueno Park");                     put("type", "park");                   }                 }),         cities             .document("TOK")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "National Museum of Nature and Science");                     put("type", "museum");                   }                 }),         cities             .document("BJ")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "Jingshan Park");                     put("type", "park");                   }                 }),         cities             .document("BJ")             .collection("landmarks")             .document()             .set(                 new HashMap<String, String>() {                   {                     put("name", "Beijing Ancient Observatory");                     put("type", "museum");                   }                 })); final List<WriteResult> landmarks = ApiFutures.allAsList(futures).get();
Python
cities = db.collection("cities")  sf_landmarks = cities.document("SF").collection("landmarks") sf_landmarks.document().set({"name": "Golden Gate Bridge", "type": "bridge"}) sf_landmarks.document().set({"name": "Legion of Honor", "type": "museum"}) la_landmarks = cities.document("LA").collection("landmarks") la_landmarks.document().set({"name": "Griffith Park", "type": "park"}) la_landmarks.document().set({"name": "The Getty", "type": "museum"}) dc_landmarks = cities.document("DC").collection("landmarks") dc_landmarks.document().set({"name": "Lincoln Memorial", "type": "memorial"}) dc_landmarks.document().set(     {"name": "National Air and Space Museum", "type": "museum"} ) tok_landmarks = cities.document("TOK").collection("landmarks") tok_landmarks.document().set({"name": "Ueno Park", "type": "park"}) tok_landmarks.document().set(     {"name": "National Museum of Nature and Science", "type": "museum"} ) bj_landmarks = cities.document("BJ").collection("landmarks") bj_landmarks.document().set({"name": "Jingshan Park", "type": "park"}) bj_landmarks.document().set(     {"name": "Beijing Ancient Observatory", "type": "museum"} )

Python

cities = db.collection("cities")  sf_landmarks = cities.document("SF").collection("landmarks") await sf_landmarks.document().set({"name": "Golden Gate Bridge", "type": "bridge"}) await sf_landmarks.document().set({"name": "Legion of Honor", "type": "museum"}) la_landmarks = cities.document("LA").collection("landmarks") await la_landmarks.document().set({"name": "Griffith Park", "type": "park"}) await la_landmarks.document().set({"name": "The Getty", "type": "museum"}) dc_landmarks = cities.document("DC").collection("landmarks") await dc_landmarks.document().set({"name": "Lincoln Memorial", "type": "memorial"}) await dc_landmarks.document().set(     {"name": "National Air and Space Museum", "type": "museum"} ) tok_landmarks = cities.document("TOK").collection("landmarks") await tok_landmarks.document().set({"name": "Ueno Park", "type": "park"}) await tok_landmarks.document().set(     {"name": "National Museum of Nature and Science", "type": "museum"} ) bj_landmarks = cities.document("BJ").collection("landmarks") await bj_landmarks.document().set({"name": "Jingshan Park", "type": "park"}) await bj_landmarks.document().set(     {"name": "Beijing Ancient Observatory", "type": "museum"} )
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
const citiesRef = db.collection('cities');  await citiesRef.doc('SF').collection('landmarks').doc().set({   name: 'Golden Gate Bridge',   type: 'bridge' }); await citiesRef.doc('SF').collection('landmarks').doc().set({   name: 'Legion of Honor',   type: 'museum' }); await citiesRef.doc('LA').collection('landmarks').doc().set({   name: 'Griffith Park',   type: 'park' }); await citiesRef.doc('LA').collection('landmarks').doc().set({   name: 'The Getty',   type: 'museum' }); await citiesRef.doc('DC').collection('landmarks').doc().set({   name: 'Lincoln Memorial',   type: 'memorial' }); await citiesRef.doc('DC').collection('landmarks').doc().set({   name: 'National Air and Space Museum',   type: 'museum' }); await citiesRef.doc('TOK').collection('landmarks').doc().set({   name: 'Ueno Park',   type: 'park' }); await citiesRef.doc('TOK').collection('landmarks').doc().set({   name: 'National Museum of Nature and Science',   type: 'museum' }); await citiesRef.doc('BJ').collection('landmarks').doc().set({   name: 'Jingshan Park',   type: 'park' }); await citiesRef.doc('BJ').collection('landmarks').doc().set({    name: 'Beijing Ancient Observatory',   type: 'museum' });
Go
import ( 	"context" 	"fmt"  	"cloud.google.com/go/firestore" )  // collectionGroupSetup sets up a collection group to query. func collectionGroupSetup(projectID, cityCollection string) error { 	ctx := context.Background()  	client, err := firestore.NewClient(ctx, projectID) 	if err != nil { 		return fmt.Errorf("firestore.NewClient: %w", err) 	} 	defer client.Close()  	landmarks := []struct { 		city, name, t string 	}{ 		{"SF", "Golden Gate Bridge", "bridge"}, 		{"SF", "Legion of Honor", "museum"}, 		{"LA", "Griffith Park", "park"}, 		{"LA", "The Getty", "museum"}, 		{"DC", "Lincoln Memorial", "memorial"}, 		{"DC", "National Air and Space Museum", "museum"}, 		{"TOK", "Ueno Park", "park"}, 		{"TOK", "National Museum of Nature and Science", "museum"}, 		{"BJ", "Jingshan Park", "park"}, 		{"BJ", "Beijing Ancient Observatory", "museum"}, 	}  	cities := client.Collection(cityCollection) 	for _, l := range landmarks { 		if _, err := cities.Doc(l.city).Collection("landmarks").NewDoc().Set(ctx, map[string]string{ 			"name": l.name, 			"type": l.t, 		}); err != nil { 			return fmt.Errorf("Set: %w", err) 		} 	}  	return nil } 
PHP
$citiesRef = $db->collection('samples/php/cities'); $citiesRef->document('SF')->collection('landmarks')->newDocument()->set([     'name' => 'Golden Gate Bridge',     'type' => 'bridge' ]); $citiesRef->document('SF')->collection('landmarks')->newDocument()->set([     'name' => 'Legion of Honor',     'type' => 'museum' ]); $citiesRef->document('LA')->collection('landmarks')->newDocument()->set([     'name' => 'Griffith Park',     'type' => 'park' ]); $citiesRef->document('LA')->collection('landmarks')->newDocument()->set([     'name' => 'The Getty',     'type' => 'museum' ]); $citiesRef->document('DC')->collection('landmarks')->newDocument()->set([     'name' => 'Lincoln Memorial',     'type' => 'memorial' ]); $citiesRef->document('DC')->collection('landmarks')->newDocument()->set([     'name' => 'National Air and Space Museum',     'type' => 'museum' ]); $citiesRef->document('TOK')->collection('landmarks')->newDocument()->set([     'name' => 'Ueno Park',     'type' => 'park' ]); $citiesRef->document('TOK')->collection('landmarks')->newDocument()->set([     'name' => 'National Museum of Nature and Science',     'type' => 'museum' ]); $citiesRef->document('BJ')->collection('landmarks')->newDocument()->set([     'name' => 'Jingshan Park',     'type' => 'park' ]); $citiesRef->document('BJ')->collection('landmarks')->newDocument()->set([     'name' => 'Beijing Ancient Observatory',     'type' => 'museum' ]); print('Added example landmarks collections to the cities collection.' . PHP_EOL);
Unity
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#
// Copyright(c) 2017 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License.  using Google.Cloud.Firestore; using Google.Cloud.Firestore.Admin.V1; using Google.Protobuf.WellKnownTypes; using Grpc.Core; using System; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using static Google.Cloud.Firestore.Admin.V1.Index.Types;  namespace GoogleCloudSamples {     public class QueryData     {         public static string Usage = @"Usage: C:\> dotnet run command YOUR_PROJECT_ID  Where command is one of     query-create-examples     create-query-state     create-query-capital     simple-queries     array-contains-query     array-contains-any-query     in-query     in-query-array     collection-group-query     subcollection-query     chained-query     composite-index-chained-query     range-query     multiple-inequalities ";         private static async Task QueryCreateExamples(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             // Note: the extra braces here are just to allow multiple citiesRef local variables.             {                 CollectionReference citiesRef = db.Collection("cities");                 await citiesRef.Document("SF").SetAsync(new Dictionary<string, object>                 {                     { "Name", "San Francisco" },                     { "State", "CA" },                     { "Country", "USA" },                     { "Capital", false },                     { "Population", 860000 },                     { "Density", 18000 },                     { "Regions", new[] {"west_coast", "norcal"} }                 });                 await citiesRef.Document("LA").SetAsync(new Dictionary<string, object>                 {                     { "Name", "Los Angeles" },                     { "State", "CA" },                     { "Country", "USA" },                     { "Capital", false },                     { "Population", 3900000 },                     { "Density", 8300 },                     { "Regions", new[] {"west_coast", "socal"} }                 });                 await citiesRef.Document("DC").SetAsync(new Dictionary<string, object>                 {                     { "Name", "Washington D.C." },                     { "State", null },                     { "Country", "USA" },                     { "Capital", true },                     { "Population", 680000 },                     { "Density", 11300 },                     { "Regions", new[] {"east_coast"} }                 });                 await citiesRef.Document("TOK").SetAsync(new Dictionary<string, object>                 {                     { "Name", "Tokyo" },                     { "State", null },                     { "Country", "Japan" },                     { "Capital", true },                     { "Population", 9000000 },                     { "Density", 16000 },                     { "Regions", new[] {"kanto", "honshu"} }                 });                 await citiesRef.Document("BJ").SetAsync(new Dictionary<string, object>                 {                     { "Name", "Beijing" },                     { "State", null },                     { "Country", "China" },                     { "Capital", true },                     { "Population", 21500000 },                     { "Density", 3500 },                     { "Regions", new[] {"jingjinji", "hebei"} }                 });                 Console.WriteLine("Added example cities data to the cities collection.");             }              {                 CollectionReference citiesRef = db.Collection("cities");                 await citiesRef.Document("SF").Collection("landmarks").Document()                     .SetAsync(new { Name = "Golden Gate Bridge", Type = "bridge" });                 await citiesRef.Document("SF").Collection("landmarks").Document()                     .SetAsync(new { Name = "Legion of Honor", Type = "museum" });                 await citiesRef.Document("LA").Collection("landmarks").Document()                     .SetAsync(new { Name = "Griffith Park", Type = "park" });                 await citiesRef.Document("DC").Collection("landmarks").Document()                     .SetAsync(new { Name = "Lincoln Memorial", Type = "memorial" });                 await citiesRef.Document("DC").Collection("landmarks").Document()                     .SetAsync(new { Name = "National Air And Space Museum", Type = "museum" });                 await citiesRef.Document("TOK").Collection("landmarks").Document()                     .SetAsync(new { Name = "Ueno Park", Type = "park" });                 await citiesRef.Document("TOK").Collection("landmarks").Document()                     .SetAsync(new { Name = "National Museum of Nature and Science", Type = "museum" });                 await citiesRef.Document("BJ").Collection("landmarks").Document()                     .SetAsync(new { Name = "Jingshan Park", Type = "park" });                 await citiesRef.Document("BJ").Collection("landmarks").Document()                     .SetAsync(new { Name = "Beijing Ancient Observatory", Type = "museum" });             }         }          private static async Task CreateQueryState(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query query = citiesRef.WhereEqualTo("State", "CA");             QuerySnapshot querySnapshot = await query.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query State=CA", documentSnapshot.Id);             }         }          private static async Task CreateQueryCapital(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query query = citiesRef.WhereEqualTo("Capital", true);             QuerySnapshot querySnapshot = await query.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query Capital=true", documentSnapshot.Id);             }         }          private static async Task SimpleQueries(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query stateQuery = citiesRef.WhereEqualTo("State", "CA");             Query populationQuery = citiesRef.WhereGreaterThan("Population", 1000000);             Query nameQuery = citiesRef.WhereGreaterThanOrEqualTo("Name", "San Francisco");             QuerySnapshot stateQuerySnapshot = await stateQuery.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in stateQuerySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query State=CA", documentSnapshot.Id);             }             QuerySnapshot populationQuerySnapshot = await populationQuery.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in populationQuerySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query Population>1000000", documentSnapshot.Id);             }             QuerySnapshot nameQuerySnapshot = await nameQuery.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in nameQuerySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query Name>=San Francisco", documentSnapshot.Id);             }         }          private static async Task ArrayContainsQuery(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query query = citiesRef.WhereArrayContains("Regions", "west_coast");             QuerySnapshot querySnapshot = await query.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query 'Regions array_contains west_coast'", documentSnapshot.Id);             }         }          private static async Task ArrayContainsAnyQuery(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query query = citiesRef.WhereArrayContainsAny("Regions", new[] { "west_coast", "east_coast" });             QuerySnapshot querySnapshot = await query.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query 'Regions array_contains_any {{west_coast, east_coast}}'", documentSnapshot.Id);             }         }          private static async Task InQueryWithoutArray(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query query = citiesRef.WhereIn("Country", new[] { "USA", "Japan" });             QuerySnapshot querySnapshot = await query.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query 'Country in {{USA, Japan}}'", documentSnapshot.Id);             }         }          private static async Task InQueryWithArray(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query query = citiesRef.WhereIn("Regions",                 new[] { new[] { "west_coast" }, new[] { "east_coast" } });             QuerySnapshot querySnapshot = await query.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query 'Regions in {{west_coast}}, {{east_coast}}'", documentSnapshot.Id);             }         }          private static async Task CollectionGroupQuery(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             Query museums = db.CollectionGroup("landmarks").WhereEqualTo("Type", "museum");             QuerySnapshot querySnapshot = await museums.GetSnapshotAsync();             foreach (DocumentSnapshot document in querySnapshot.Documents)             {                 Console.WriteLine($"{document.Reference.Path}: {document.GetValue<string>("Name")}");             }         }          private static async Task SubcollectionQuery(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference landmarks = db.Collection("cities").Document("SF").Collection("landmarks");             QuerySnapshot querySnapshot = await landmarks.GetSnapshotAsync();             foreach (DocumentSnapshot document in querySnapshot.Documents)             {                 Console.WriteLine($"{document.Reference.Path}: {document.GetValue<string>("Name")}");             }         }          private static async Task ChainedQuery(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query chainedQuery = citiesRef                 .WhereEqualTo("State", "CA")                 .WhereEqualTo("Name", "San Francisco");             QuerySnapshot querySnapshot = await chainedQuery.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query State=CA and Name=San Francisco", documentSnapshot.Id);             }         }          private static async Task CompositeIndexChainedQuery(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query chainedQuery = citiesRef                 .WhereEqualTo("State", "CA")                 .WhereLessThan("Population", 1000000);             QuerySnapshot querySnapshot = await chainedQuery.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query State=CA and Population<1000000", documentSnapshot.Id);             }         }          private static async Task RangeQuery(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             CollectionReference citiesRef = db.Collection("cities");             Query rangeQuery = citiesRef                 .WhereGreaterThanOrEqualTo("State", "CA")                 .WhereLessThanOrEqualTo("State", "IN");             QuerySnapshot querySnapshot = await rangeQuery.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents)             {                 Console.WriteLine("Document {0} returned by query CA<=State<=IN", documentSnapshot.Id);             }         }          private static async Task MultipleInequalitiesQuery(string project)         {             FirestoreDb db = FirestoreDb.Create(project);             FirestoreAdminClient adminClient = FirestoreAdminClient.Create();             var index = new Google.Cloud.Firestore.Admin.V1.Index             {                 Fields =                 {                     new IndexField { FieldPath = "Density", Order = IndexField.Types.Order.Ascending },                     new IndexField { FieldPath = "Population", Order = IndexField.Types.Order.Ascending }                 },                 QueryScope = QueryScope.Collection             };              // We speculatively try to create the index, and just ignore an error of it already existing.             try             {                 var lro = await adminClient.CreateIndexAsync(new CollectionGroupName(db.ProjectId, db.DatabaseId, "cities"), index);                 await lro.PollUntilCompletedAsync();             }             catch (RpcException ex) when (ex.StatusCode == StatusCode.AlreadyExists)             {                 // Assume the index is okay.             }              CollectionReference citiesRef = db.Collection("cities");             Query query = citiesRef                 .WhereGreaterThan("Population", 1000000)                 .WhereLessThan("Density", 10000);             QuerySnapshot querySnapshot = await query.GetSnapshotAsync();             foreach (DocumentSnapshot documentSnapshot in querySnapshot)             {                 var name = documentSnapshot.GetValue<string>("Name");                 var population = documentSnapshot.GetValue<int>("Population");                 var density = documentSnapshot.GetValue<int>("Density");                 Console.WriteLine($"City '{name}' returned by query. Population={population}; Density={density}");             }         }          public static void Main(string[] args)         {             if (args.Length < 2)             {                 Console.Write(Usage);                 return;             }             string command = args[0].ToLower();             string project = string.Join(" ",                 new ArraySegment<string>(args, 1, args.Length - 1));             switch (command)             {                 case "query-create-examples":                     QueryCreateExamples(project).Wait();                     break;                  case "create-query-state":                     CreateQueryState(project).Wait();                     break;                  case "create-query-capital":                     CreateQueryCapital(project).Wait();                     break;                  case "simple-queries":                     SimpleQueries(project).Wait();                     break;                  case "array-contains-query":                     ArrayContainsQuery(project).Wait();                     break;                  case "array-contains-any-query":                     ArrayContainsAnyQuery(project).Wait();                     break;                  case "in-query":                     InQueryWithoutArray(project).Wait();                     break;                  case "in-query-array":                     InQueryWithArray(project).Wait();                     break;                  case "collection-group-query":                     CollectionGroupQuery(project).Wait();                     break;                  case "subcollection-query":                     SubcollectionQuery(project).Wait();                     break;                  case "chained-query":                     ChainedQuery(project).Wait();                     break;                  case "composite-index-chained-query":                     CompositeIndexChainedQuery(project).Wait();                     break;                  case "range-query":                     RangeQuery(project).Wait();                     break;                  case "multiple-inequalities":                     MultipleInequalitiesQuery(project).Wait();                     break;                  default:                     Console.Write(Usage);                     return;             }         }     } } 
Ruby
cities_ref = firestore.col collection_path  sf_landmarks = cities_ref.document("SF").collection("landmarks") sf_landmarks.document.set(   {     name: "Golden Gate Bridge",     type: "bridge"   } ) sf_landmarks.document.set(   {     name: "Legion of Honor",     type: "museum"   } )  la_landmarks = cities_ref.document("LA").collection("landmarks") la_landmarks.document.set(   {     name: "Griffith Park",     type: "park"   } ) la_landmarks.document.set(   {     name: "The Getty",     type: "museum"   } )  dc_landmarks = cities_ref.document("DC").collection("landmarks") dc_landmarks.document.set(   {     name: "Lincoln Memorial",     type: "memorial"   } ) dc_landmarks.document.set(   {     name: "National Air and Space Museum",     type: "museum"   } )  tok_landmarks = cities_ref.document("TOK").collection("landmarks") tok_landmarks.document.set(   {     name: "Ueno Park",     type: "park"   } ) tok_landmarks.document.set(   {     name: "National Museum of Nature and Science",     type: "museum"   } )  bj_landmarks = cities_ref.document("BJ").collection("landmarks") bj_landmarks.document.set(   {     name: "Jingshan Park",     type: "park"   } ) bj_landmarks.document.set(   {     name: "Beijing Ancient Observatory",     type: "museum"   } )

我们可以使用之前介绍的简单查询和复合查询来查询单个城市的 landmarks 子集合,但您可能还需要同时从每个城市的 landmarks 子集合中检索结果。

landmarks 集合组包含 ID 为 landmarks 的所有集合,您可以使用集合组查询进行查询。例如,此集合组查询会检索所有城市的所有 museum 地标:

Web

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

var museums = db.collectionGroup('landmarks').where('type', '==', 'museum'); museums.get().then((querySnapshot) => {     querySnapshot.forEach((doc) => {         console.log(doc.id, ' => ', doc.data());     }); });
Swift
注意:此产品不适用于 watchOS 和 App Clip 目标。
db.collectionGroup("landmarks").whereField("type", isEqualTo: "museum").getDocuments { (snapshot, error) in   // ... }
Objective-C
注意:此产品不适用于 watchOS 和 App Clip 目标。
[[[self.db collectionGroupWithID:@"landmarks"] queryWhereField:@"type" isEqualTo:@"museum"]     getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) {     // ... }];

Kotlin

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
final Query museums = db.collectionGroup("landmarks").whereEqualTo("type", "museum"); final ApiFuture<QuerySnapshot> querySnapshot = museums.get(); for (DocumentSnapshot document : querySnapshot.get().getDocuments()) {   System.out.println(document.getId()); }
Python
museums = db.collection_group("landmarks").where(     filter=FieldFilter("type", "==", "museum") ) docs = museums.stream() for doc in docs:     print(f"{doc.id} => {doc.to_dict()}")

Python

museums = db.collection_group("landmarks").where(     filter=FieldFilter("type", "==", "museum") ) docs = museums.stream() async for doc in docs:     print(f"{doc.id} => {doc.to_dict()}")
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
const querySnapshot = await db.collectionGroup('landmarks').where('type', '==', 'museum').get(); querySnapshot.forEach((doc) => {   console.log(doc.id, ' => ', doc.data()); });
Go
import ( 	"context" 	"fmt" 	"io"  	"cloud.google.com/go/firestore" 	"google.golang.org/api/iterator" )  // collectionGroupQuery runs a collection group query over the data created by // collectionGroupSetup. func collectionGroupQuery(w io.Writer, projectID string) error { 	ctx := context.Background()  	client, err := firestore.NewClient(ctx, projectID) 	if err != nil { 		return fmt.Errorf("firestore.NewClient: %w", err) 	} 	defer client.Close()  	it := client.CollectionGroup("landmarks").Where("type", "==", "museum").Documents(ctx) 	for { 		doc, err := it.Next() 		if err == iterator.Done { 			break 		} 		if err != nil { 			return fmt.Errorf("documents iterator: %w", err) 		} 		fmt.Fprintf(w, "%s: %s", doc.Ref.ID, doc.Data()["name"]) 	}  	return nil } 
PHP
$museums = $db->collectionGroup('landmarks')->where('type', '==', 'museum'); foreach ($museums->documents() as $document) {     printf('%s => %s' . PHP_EOL, $document->id(), $document->data()['name']); }
Unity
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#
Query museums = db.CollectionGroup("landmarks").WhereEqualTo("Type", "museum"); QuerySnapshot querySnapshot = await museums.GetSnapshotAsync(); foreach (DocumentSnapshot document in querySnapshot.Documents) {     Console.WriteLine($"{document.Reference.Path}: {document.GetValue<string>("Name")}"); }
Ruby
museums = firestore.collection_group("landmarks").where("type", "==", "museum") museums.get do |museum|   puts "#{museum[:type]} name is #{museum[:name]}." end

在使用集合组查询之前,您必须创建支持集合组查询的索引。您可以通过错误消息、控制台或 Firebase CLI 创建索引

对于 Web 和移动 SDK,您还必须创建允许集合组查询的规则

解释查询性能

借助 Cloud Firestore,您可以衡量后端查询的性能,并获得后端查询执行的详细性能统计信息。

查询解释结果可以帮助您了解查询是如何执行的,向您揭示低效问题,并指明可能存在服务器端瓶颈的位置。

如需了解详情,请参阅“查询解释”指南

查询限制

以下列表总结了 Cloud Firestore 查询的限制:

  • Cloud Firestore 支持通过 orinarray-contains-any 运算符进行逻辑 OR 查询。这些查询最多只能包含 30 个析取运算(基于查询的析取范式)
  • 每个析取运算(or 组)最多只能使用一个 array-contains 子句。不能在同一析取运算中将 array-containsarray-contains-any 组合使用。
  • 不能在同一查询中将 not-ininarray-contains-anyor 组合使用。
  • 每个查询只允许有一个 not-in!=
  • not-in 最多支持 10 个比较值。
  • 一个查询中的过滤条件、排序顺序和父级文档路径(1 表示子集合、0 表示根集合)的总和不能超过 100。此数值是基于查询的析取范式计算得出的。
  • 如果查询对某个字段使用不等式过滤条件,则系统会按该字段进行排序并按该字段是否存在进行过滤

OR 查询的限制

为防止查询的计算费用过高,Cloud Firestore 会限制您可以组合使用的 ANDOR 子句的数量。为了应用此限制,Cloud Firestore 会将执行逻辑 OR 运算(orinarray-contains-any)的查询转换为析取范式(也称为 ANDOR)。Cloud Firestore 允许一个查询最多包含 30 个析取运算(以析取范式形式)。

析取范式

Cloud Firestore 通过应用以下两项规则,将查询转换为析取范式:

  • Flatten

    假定有 ABC 这 3 个条件:

    A and (B and C) => A and B and C

  • 分配率

    假定有 ABCD 这 4 个条件:

    • 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)

inarray-contains-any 查询应用这些规则时,请注意这些运算符都是 OR 的简写形式。例如,a in [1,2]a = 1 OR a = 2 的简写形式。

以下示例展示了不同查询的析取运算数:

查询析取运算数
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

此查询的析取范式与上述查询相同。

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

由于超出析取运算数上限(30 个),此查询返回错误。

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 及其存在性

当您按给定字段对查询进行排序时,查询只会返回存在排序依据 (order-by) 字段的文档。

例如,以下查询不会返回任何未设置 population 字段的文档,即使它们符合查询过滤条件也是如此。

Java
db.collection("cities").whereEqualTo("country", USA).orderBy(population);

类似的规则也适用于不等式。如果查询对某个字段使用不等式过滤条件,则系统会按该字段进行排序。以下查询不会返回不含 population 字段的文档,即使该文档中有 country = USA 也是如此。如需解决此问题,您可以为每个排序执行单独的查询,也可以为所有排序依据字段分配一个值。

Java
db.collection(cities).where(or(country, USA), greaterThan(population, 250000));

上面查询中的不等式隐含了排序依据 (order-by),它等效于下面的查询:

Java
db.collection(cities).where(or(country, USA), greaterThan(population, 250000)).orderBy(population);

后续步骤