يوفر Cloud Firestore وظيفة استعلام قوية لتحديد المستندات التي تريد استردادها من مجموعة أو مجموعة تجميع. يمكن أيضًا استخدام هذه الاستعلامات مع get()
أو addSnapshotListener()
، كما هو موضح في الحصول على البيانات والحصول على التحديثات في الوقت الفعلي .
بيانات المثال
للبدء، اكتب بعض البيانات حول المدن حتى نتمكن من البحث عن طرق مختلفة لقراءتها مرة أخرى:
Web modular API
import { collection, doc, setDoc } from "firebase/firestore"; const citiesRef = collection(db, "cities"); await setDoc(doc(citiesRef, "SF"), { name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860000, regions: ["west_coast", "norcal"] }); await setDoc(doc(citiesRef, "LA"), { name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3900000, regions: ["west_coast", "socal"] }); await setDoc(doc(citiesRef, "DC"), { name: "Washington, D.C.", state: null, country: "USA", capital: true, population: 680000, regions: ["east_coast"] }); await setDoc(doc(citiesRef, "TOK"), { name: "Tokyo", state: null, country: "Japan", capital: true, population: 9000000, regions: ["kanto", "honshu"] }); await setDoc(doc(citiesRef, "BJ"), { name: "Beijing", state: null, country: "China", capital: true, population: 21500000, regions: ["jingjinji", "hebei"] });
Web namespaced API
var citiesRef = db.collection("cities"); citiesRef.doc("SF").set({ name: "San Francisco", state: "CA", country: "USA", capital: false, population: 860000, regions: ["west_coast", "norcal"] }); citiesRef.doc("LA").set({ name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 3900000, regions: ["west_coast", "socal"] }); citiesRef.doc("DC").set({ name: "Washington, D.C.", state: null, country: "USA", capital: true, population: 680000, regions: ["east_coast"] }); citiesRef.doc("TOK").set({ name: "Tokyo", state: null, country: "Japan", capital: true, population: 9000000, regions: ["kanto", "honshu"] }); citiesRef.doc("BJ").set({ name: "Beijing", state: null, country: "China", capital: true, population: 21500000, regions: ["jingjinji", "hebei"] });
سويفت
let citiesRef = db.collection("cities") citiesRef.document("SF").setData([ "name": "San Francisco", "state": "CA", "country": "USA", "capital": false, "population": 860000, "regions": ["west_coast", "norcal"] ]) citiesRef.document("LA").setData([ "name": "Los Angeles", "state": "CA", "country": "USA", "capital": false, "population": 3900000, "regions": ["west_coast", "socal"] ]) citiesRef.document("DC").setData([ "name": "Washington D.C.", "country": "USA", "capital": true, "population": 680000, "regions": ["east_coast"] ]) citiesRef.document("TOK").setData([ "name": "Tokyo", "country": "Japan", "capital": true, "population": 9000000, "regions": ["kanto", "honshu"] ]) citiesRef.document("BJ").setData([ "name": "Beijing", "country": "China", "capital": true, "population": 21500000, "regions": ["jingjinji", "hebei"] ])
ج موضوعية
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [[citiesRef documentWithPath:@"SF"] setData:@{ @"name": @"San Francisco", @"state": @"CA", @"country": @"USA", @"capital": @(NO), @"population": @860000, @"regions": @[@"west_coast", @"norcal"] }]; [[citiesRef documentWithPath:@"LA"] setData:@{ @"name": @"Los Angeles", @"state": @"CA", @"country": @"USA", @"capital": @(NO), @"population": @3900000, @"regions": @[@"west_coast", @"socal"] }]; [[citiesRef documentWithPath:@"DC"] setData:@{ @"name": @"Washington D.C.", @"country": @"USA", @"capital": @(YES), @"population": @680000, @"regions": @[@"east_coast"] }]; [[citiesRef documentWithPath:@"TOK"] setData:@{ @"name": @"Tokyo", @"country": @"Japan", @"capital": @(YES), @"population": @9000000, @"regions": @[@"kanto", @"honshu"] }]; [[citiesRef documentWithPath:@"BJ"] setData:@{ @"name": @"Beijing", @"country": @"China", @"capital": @(YES), @"population": @21500000, @"regions": @[@"jingjinji", @"hebei"] }];
Kotlin+KTX
val cities = db.collection("cities") val data1 = hashMapOf( "name" to "San Francisco", "state" to "CA", "country" to "USA", "capital" to false, "population" to 860000, "regions" to listOf("west_coast", "norcal"), ) cities.document("SF").set(data1) val data2 = hashMapOf( "name" to "Los Angeles", "state" to "CA", "country" to "USA", "capital" to false, "population" to 3900000, "regions" to listOf("west_coast", "socal"), ) cities.document("LA").set(data2) val data3 = hashMapOf( "name" to "Washington D.C.", "state" to null, "country" to "USA", "capital" to true, "population" to 680000, "regions" to listOf("east_coast"), ) cities.document("DC").set(data3) val data4 = hashMapOf( "name" to "Tokyo", "state" to null, "country" to "Japan", "capital" to true, "population" to 9000000, "regions" to listOf("kanto", "honshu"), ) cities.document("TOK").set(data4) val data5 = hashMapOf( "name" to "Beijing", "state" to null, "country" to "China", "capital" to true, "population" to 21500000, "regions" to listOf("jingjinji", "hebei"), ) cities.document("BJ").set(data5)
Java
CollectionReference cities = db.collection("cities"); Map<String, Object> data1 = new HashMap<>(); data1.put("name", "San Francisco"); data1.put("state", "CA"); data1.put("country", "USA"); data1.put("capital", false); data1.put("population", 860000); data1.put("regions", Arrays.asList("west_coast", "norcal")); cities.document("SF").set(data1); Map<String, Object> data2 = new HashMap<>(); data2.put("name", "Los Angeles"); data2.put("state", "CA"); data2.put("country", "USA"); data2.put("capital", false); data2.put("population", 3900000); data2.put("regions", Arrays.asList("west_coast", "socal")); cities.document("LA").set(data2); Map<String, Object> data3 = new HashMap<>(); data3.put("name", "Washington D.C."); data3.put("state", null); data3.put("country", "USA"); data3.put("capital", true); data3.put("population", 680000); data3.put("regions", Arrays.asList("east_coast")); cities.document("DC").set(data3); Map<String, Object> data4 = new HashMap<>(); data4.put("name", "Tokyo"); data4.put("state", null); data4.put("country", "Japan"); data4.put("capital", true); data4.put("population", 9000000); data4.put("regions", Arrays.asList("kanto", "honshu")); cities.document("TOK").set(data4); Map<String, Object> data5 = new HashMap<>(); data5.put("name", "Beijing"); data5.put("state", null); data5.put("country", "China"); data5.put("capital", true); data5.put("population", 21500000); data5.put("regions", Arrays.asList("jingjinji", "hebei")); cities.document("BJ").set(data5);
Dart
final cities = db.collection("cities"); final data1 = <String, dynamic>{ "name": "San Francisco", "state": "CA", "country": "USA", "capital": false, "population": 860000, "regions": ["west_coast", "norcal"] }; cities.doc("SF").set(data1); final data2 = <String, dynamic>{ "name": "Los Angeles", "state": "CA", "country": "USA", "capital": false, "population": 3900000, "regions": ["west_coast", "socal"], }; cities.doc("LA").set(data2); final data3 = <String, dynamic>{ "name": "Washington D.C.", "state": null, "country": "USA", "capital": true, "population": 680000, "regions": ["east_coast"] }; cities.doc("DC").set(data3); final data4 = <String, dynamic>{ "name": "Tokyo", "state": null, "country": "Japan", "capital": true, "population": 9000000, "regions": ["kanto", "honshu"] }; cities.doc("TOK").set(data4); final data5 = <String, dynamic>{ "name": "Beijing", "state": null, "country": "China", "capital": true, "population": 21500000, "regions": ["jingjinji", "hebei"], }; cities.doc("BJ").set(data5);
جافا
بايثون
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() )
سي ++
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
يذهب
بي أتش بي
وحدة
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"} } });
ج#
روبي
استفسارات بسيطة
يقوم الاستعلام التالي بإرجاع جميع المدن ذات الولاية CA
:
Web modular API
// Create a reference to the cities collection import { collection, query, where } from "firebase/firestore"; const citiesRef = collection(db, "cities"); // Create a query against the collection. const q = query(citiesRef, where("state", "==", "CA"));
Web namespaced API
// Create a reference to the cities collection var citiesRef = db.collection("cities"); // Create a query against the collection. var query = citiesRef.where("state", "==", "CA");
سويفت
// Create a reference to the cities collection let citiesRef = db.collection("cities") // Create a query against the collection. let query = citiesRef.whereField("state", isEqualTo: "CA")
ج موضوعية
// Create a reference to the cities collection FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; // Create a query against the collection. FIRQuery *query = [citiesRef queryWhereField:@"state" isEqualTo:@"CA"];
Kotlin+KTX
// Create a reference to the cities collection val citiesRef = db.collection("cities") // Create a query against the collection. val query = citiesRef.whereEqualTo("state", "CA")
Java
// Create a reference to the cities collection CollectionReference citiesRef = db.collection("cities"); // Create a query against the collection. Query query = citiesRef.whereEqualTo("state", "CA");
Dart
// Create a reference to the cities collection final citiesRef = db.collection("cities"); // Create a query against the collection. final query = citiesRef.where("state", isEqualTo: "CA");
جافا
بايثون
Python
سي ++
CollectionReference cities_ref = db->Collection("cities"); // Create a query against the collection. Query query_ca = cities_ref.WhereEqualTo("state", FieldValue::String("CA"));
Node.js
يذهب
بي أتش بي
وحدة
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)); } });
ج #
روبي
يقوم الاستعلام التالي بإرجاع جميع العواصم:
Web modular API
import { collection, query, where } from "firebase/firestore"; const citiesRef = collection(db, "cities"); const q = query(citiesRef, where("capital", "==", true));
Web namespaced API
var citiesRef = db.collection("cities"); var query = citiesRef.where("capital", "==", true);
سويفت
let capitalCities = db.collection("cities").whereField("capital", isEqualTo: true)
ج موضوعية
FIRQuery *capitalCities = [[self.db collectionWithPath:@"cities"] queryWhereField:@"capital" isEqualTo:@YES];
Kotlin+KTX
val capitalCities = db.collection("cities").whereEqualTo("capital", true)
Java
Query capitalCities = db.collection("cities").whereEqualTo("capital", true);
Dart
final capitalcities = db.collection("cities").where("capital", isEqualTo: true);
جافا
بايثون
Python
سي ++
Query capital_cities = db->Collection("cities").WhereEqualTo( "capital", FieldValue::Boolean(true));
Node.js
يذهب
بي أتش بي
وحدة
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)); } });
ج #
روبي
تنفيذ استعلام
بعد إنشاء كائن استعلام، استخدم الدالة get()
لاسترداد النتائج:
Web modular API
import { collection, query, where, getDocs } from "firebase/firestore"; const q = query(collection(db, "cities"), where("capital", "==", true)); const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots console.log(doc.id, " => ", doc.data()); });
Web namespaced API
db.collection("cities").where("capital", "==", true) .get() .then((querySnapshot) => { querySnapshot.forEach((doc) => { // doc.data() is never undefined for query doc snapshots console.log(doc.id, " => ", doc.data()); }); }) .catch((error) => { console.log("Error getting documents: ", error); });
سويفت
db.collection("cities").whereField("capital", isEqualTo: true) .getDocuments() { (querySnapshot, err) in if let err = err { print("Error getting documents: \(err)") } else { for document in querySnapshot!.documents { print("\(document.documentID) => \(document.data())") } } }
ج موضوعية
[[[self.db collectionWithPath:@"cities"] queryWhereField:@"capital" isEqualTo:@(YES)] getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) { if (error != nil) { NSLog(@"Error getting documents: %@", error); } else { for (FIRDocumentSnapshot *document in snapshot.documents) { NSLog(@"%@ => %@", document.documentID, document.data); } } }];
Kotlin+KTX
db.collection("cities") .whereEqualTo("capital", true) .get() .addOnSuccessListener { documents -> for (document in documents) { Log.d(TAG, "${document.id} => ${document.data}") } } .addOnFailureListener { exception -> Log.w(TAG, "Error getting documents: ", exception) }
Java
db.collection("cities") .whereEqualTo("capital", true) .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { Log.d(TAG, document.getId() + " => " + document.getData()); } } else { Log.d(TAG, "Error getting documents: ", task.getException()); } } });
Dart
db.collection("cities").where("capital", isEqualTo: true).get().then( (querySnapshot) { print("Successfully completed"); for (var docSnapshot in querySnapshot.docs) { print('${docSnapshot.id} => ${docSnapshot.data()}'); } }, onError: (e) => print("Error completing: $e"), );
جافا
بايثون
Python
سي ++
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
يذهب
بي أتش بي
بي أتش بي
لمعرفة المزيد حول تثبيت وإنشاء عميل Cloud Firestore، راجع مكتبات عميل Cloud Firestore .
وحدة
Query capitalQuery = db.Collection("cities").WhereEqualTo("Capital", true); capitalQuery.GetSnapshotAsync().ContinueWithOnMainThread(task => { QuerySnapshot capitalQuerySnapshot = task.Result; foreach (DocumentSnapshot documentSnapshot in capitalQuerySnapshot.Documents) { Debug.Log(String.Format("Document data for {0} document:", documentSnapshot.Id)); Dictionary<string, object> city = documentSnapshot.ToDictionary(); foreach (KeyValuePair<string, object> pair in city) { Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value)); } // Newline to separate entries Debug.Log(""); }; });
ج #
روبي
راجع الحصول على البيانات لمزيد من المعلومات حول استرداد نتائج الاستعلام. يمكنك أيضًا إضافة مستمع إلى استعلام للحصول على النتائج الحالية والاستماع إلى التحديثات المستقبلية.
مشغلي الاستعلام
تأخذ الطريقة where()
ثلاث معلمات: حقل للتصفية، وعامل مقارنة، وقيمة. يدعم Cloud Firestore عوامل المقارنة التالية:
-
<
أقل من -
<=
أقل من أو يساوي -
==
يساوي -
>
أكبر من -
>=
أكبر من أو يساوي -
!=
لا يساوي -
array-contains
-
array-contains-any
-
in
-
not-in
على سبيل المثال:
Web modular API
const stateQuery = query(citiesRef, where("state", "==", "CA")); const populationQuery = query(citiesRef, where("population", "<", 100000)); const nameQuery = query(citiesRef, where("name", ">=", "San Francisco"));
Web namespaced API
const stateQuery = citiesRef.where("state", "==", "CA"); const populationQuery = citiesRef.where("population", "<", 100000); const nameQuery = citiesRef.where("name", ">=", "San Francisco");
سويفت
let stateQuery = citiesRef.whereField("state", isEqualTo: "CA") let populationQuery = citiesRef.whereField("population", isLessThan: 100000) let nameQuery = citiesRef.whereField("name", isGreaterThanOrEqualTo: "San Francisco")
ج موضوعية
FIRQuery *stateQuery = [citiesRef queryWhereField:@"state" isEqualTo:@"CA"]; FIRQuery *populationQuery = [citiesRef queryWhereField:@"population" isLessThan:@100000]; FIRQuery *nameQuery = [citiesRef queryWhereField:@"name" isGreaterThanOrEqualTo:@"San Francisco"];
Kotlin+KTX
val stateQuery = citiesRef.whereEqualTo("state", "CA") val populationQuery = citiesRef.whereLessThan("population", 100000) val nameQuery = citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco")
Java
Query stateQuery = citiesRef.whereEqualTo("state", "CA"); Query populationQuery = citiesRef.whereLessThan("population", 100000); Query nameQuery = citiesRef.whereGreaterThanOrEqualTo("name", "San Francisco");
Dart
final citiesRef = db.collection("cities"); final stateQuery = citiesRef.where("state", isEqualTo: "CA"); final populationQuery = citiesRef.where("population", isLessThan: 100000); final nameQuery = citiesRef.where("name", isEqualTo: "San Francisco");
جافا
بايثون
Python
سي ++
cities_ref.WhereEqualTo("state", FieldValue::String("CA")); cities_ref.WhereLessThan("population", FieldValue::Integer(100000)); cities_ref.WhereGreaterThanOrEqualTo("name", FieldValue::String("San Francisco"));
Node.js
يذهب
بي أتش بي
وحدة
Query stateQuery = citiesRef.WhereEqualTo("State", "CA"); Query populationQuery = citiesRef.WhereGreaterThan("Population", 1000000); Query nameQuery = citiesRef.WhereGreaterThanOrEqualTo("Name", "San Francisco");
ج#
روبي
لا يساوي ( !=
)
استخدم عامل التشغيل غير متساوي ( !=
) لإرجاع المستندات التي يوجد فيها الحقل المحدد ولا يتطابق مع قيمة المقارنة. على سبيل المثال:
Web modular API
const notCapitalQuery = query(citiesRef, where("capital", "!=", false));
Web namespaced API
citiesRef.where("capital", "!=", false);
سويفت
let notEqualQuery = citiesRef.whereField("capital", isNotEqualTo: false)
ج موضوعية
query = [citiesRef queryWhereField:@"capital" isNotEqualTo:@NO];
Kotlin+KTX
val notCapitalQuery = citiesRef.whereNotEqualTo("capital", false)
Java
Query notCapitalQuery = citiesRef.whereNotEqualTo("capital", false);
Dart
final citiesRef = db.collection("cities"); final notCapitals = citiesRef.where("capital", isNotEqualTo: true);
جافا
بايثون
// Snippet not yet available
سي ++
cities_ref.WhereNotEqualTo("capital", FieldValue::Boolean(false));
Node.js
يذهب
// Snippet not yet available
بي أتش بي
وحدة
Query query = citiesRef.WhereNotEqualTo("capital", false); Query query = citiesRef.WhereNotEqualTo("capital", false);
ج #
// Snippet not yet available
روبي
يقوم هذا الاستعلام بإرجاع كل مستند city
حيث يوجد حقل capital
بقيمة غير false
أو null
. يتضمن ذلك مستندات city
حيث تساوي قيمة الحقل capital
true
أو أي قيمة غير منطقية إلى جانب null
.
لا يُرجع هذا الاستعلام مستندات city
حيث لا يوجد حقل capital
. تستثني الاستعلامات غير المتساوية ( !=
) not-in
المستندات التي لا يوجد بها الحقل المحدد .
يوجد الحقل عند تعيينه على أي قيمة، بما في ذلك سلسلة فارغة ( ""
) و null
و NaN
(ليس رقمًا). لاحظ أن قيم الحقول null
لا تتطابق مع عبارات !=
، لأن x != null
يتم تقييمها على أنها undefined
.
محددات
لاحظ القيود التالية للاستعلامات !=
:
- يمكن فقط للمستندات التي يوجد بها الحقل المحدد أن تتطابق مع الاستعلام.
- لا يمكنك دمج
not-in
و!=
في استعلام مركب. - في الاستعلام المركب، يجب تصفية مقارنات النطاق (
<
,<=
,>
,>=
) وليس يساوي (!=
,not-in
) في نفس الحقل.
عضوية المصفوفة
يمكنك استخدام عامل التشغيل array-contains
للتصفية بناءً على قيم المصفوفة. على سبيل المثال:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where("regions", "array-contains", "west_coast"));
Web namespaced API
citiesRef.where("regions", "array-contains", "west_coast");
سويفت
citiesRef .whereField("regions", arrayContains: "west_coast")
ج موضوعية
[citiesRef queryWhereField:@"state" arrayContains:@"west_coast"];
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereArrayContains("regions", "west_coast")
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereArrayContains("regions", "west_coast");
Dart
final citiesRef = db.collection("cities"); final westCoastcities = citiesRef.where("regions", arrayContains: "west_coast");
جافا
بايثون
Python
سي ++
CollectionReference cities_ref = db->Collection("cities"); cities_ref.WhereArrayContains("region", FieldValue::String("west_coast"));
Node.js
يذهب
بي أتش بي
وحدة
CollectionReference citiesRef = db.Collection("cities"); Query arrayContainsQuery = citiesRef.WhereArrayContains("region", "west_coast");
ج #
روبي
يقوم هذا الاستعلام بإرجاع كل مستند city
حيث يكون حقل regions
عبارة عن مصفوفة تحتوي على west_coast
. إذا كان المصفوفة تحتوي على مثيلات متعددة للقيمة التي تستعلم عنها، فسيتم تضمين المستند في النتائج مرة واحدة فقط.
يمكنك استخدام array-contains
واحد على الأكثر لكل انفصال ( or
مجموعة). لا يمكنك دمج array-contains
على array-contains-any
في نفس الانفصال.
in
، not-in
، array-contains-any
استخدم عامل التشغيل in
لدمج ما يصل إلى 30 عبارة مساواة ( ==
) في نفس الحقل باستخدام OR
المنطقي. يقوم in
بإرجاع المستندات التي يتطابق فيها الحقل المحدد مع أي من قيم المقارنة. على سبيل المثال:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where('country', 'in', ['USA', 'Japan']));
Web namespaced API
citiesRef.where('country', 'in', ['USA', 'Japan']);
سويفت
let citiesRef = db.collection("cities") citiesRef.whereField("country", in: ["USA", "Japan"])
ج موضوعية
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [citiesRef queryWhereField:@"country" in:@[@"USA", @"Japan"]];
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereIn("country", listOf("USA", "Japan"))
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereIn("country", Arrays.asList("USA", "Japan"));
Dart
final citiesRef = db.collection("cities"); final cities = citiesRef.where("country", whereIn: ["USA", "Japan"]);
جافا
بايثون
Python
سي ++
CollectionReference cities_ref = db->Collection("cities"); cities_ref.WhereIn("country", std::vector<FieldValue> { FieldValue::String("USA"), FieldValue::String("Japan") });
Node.js
يذهب
بي أتش بي
وحدة
CollectionReference citiesRef = db.Collection("cities"); ListcountriesList = new List<object>() {"USA", "Japan"}; Query whereInQuery = citiesRef.WhereIn("country", countriesList);
ج #
روبي
يقوم هذا الاستعلام بإرجاع كل مستند city
حيث تم تعيين حقل country
إلى USA
أو Japan
. من بيانات المثال، يتضمن ذلك مستندات SF
و LA
و DC
و TOK
.
not-in
استخدم عامل التشغيل not-in
لدمج ما يصل إلى 10 عبارات غير متساوية ( !=
) في نفس الحقل باستخدام AND
المنطقية. يقوم الاستعلام not-in
بإرجاع المستندات التي يوجد بها الحقل المحدد، وليس null
، ولا يطابق أيًا من قيم المقارنة. على سبيل المثال:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where('country', 'not-in', ['USA', 'Japan']));
Web namespaced API
citiesRef.where('country', 'not-in', ['USA', 'Japan']);
سويفت
citiesRef.whereField("country", notIn: ["USA", "Japan"])
ج موضوعية
[citiesRef queryWhereField:@"country" notIn:@[@"USA", @"Japan"]];
Kotlin+KTX
citiesRef.whereNotIn("country", listOf("USA", "Japan"))
Java
citiesRef.whereNotIn("country", Arrays.asList("USA", "Japan"));
Dart
final citiesRef = db.collection("cities"); final cities = citiesRef.where("country", whereNotIn: ["USA", "Japan"]);
جافا
بايثون
// Snippet not yet available
سي ++
cities_ref.WhereNotIn("country", std::vector<FieldValue> { FieldValue::String("USA"), FieldValue::String("Japan") });
Node.js
يذهب
// Snippet not yet available
بي أتش بي
وحدة
Query query = citiesRef.WhereNotIn(new FieldPath("country"), new List<string>{"USA", "Japan"}); Query query = citiesRef.WhereNotIn("country", new List<object>(){"USA", "Japan"});
ج #
// Snippet not yet available
روبي
يقوم هذا الاستعلام بإرجاع كل مستند city
حيث يوجد حقل country
ولم يتم تعيينه على USA
أو Japan
أو null
. ومن بيانات المثال، يتضمن هذا مستندات London
Hong Kong
.
استعلامات not-in
تستبعد المستندات التي لا يوجد فيها الحقل المحدد. يوجد الحقل عند تعيينه على أي قيمة، بما في ذلك سلسلة فارغة ( ""
) و null
و NaN
(ليس رقمًا). لاحظ أن x != null
يتم تقييمه على أنه undefined
. الاستعلام not-in
الذي يحتوي على قيمة null
كأحد قيم المقارنة لا يطابق أي مستندات.
array-contains-any
استخدم عامل التشغيل array-contains-any
لدمج ما يصل إلى 30 array-contains
صفيف في نفس الحقل باستخدام OR
المنطقي. يقوم استعلام array-contains-any
بإرجاع المستندات حيث يكون الحقل المحدد عبارة عن مصفوفة تحتوي على واحدة أو أكثر من قيم المقارنة:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where('regions', 'array-contains-any', ['west_coast', 'east_coast']));
Web namespaced API
citiesRef.where('regions', 'array-contains-any', ['west_coast', 'east_coast']);
سويفت
let citiesRef = db.collection("cities") citiesRef.whereField("regions", arrayContainsAny: ["west_coast", "east_coast"])
ج موضوعية
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; [citiesRef queryWhereField:@"regions" arrayContainsAny:@[@"west_coast", @"east_coast"]];
Kotlin+KTX
val citiesRef = db.collection("cities") citiesRef.whereArrayContainsAny("regions", listOf("west_coast", "east_coast"))
Java
CollectionReference citiesRef = db.collection("cities"); citiesRef.whereArrayContainsAny("regions", Arrays.asList("west_coast", "east_coast"));
Dart
final citiesRef = db.collection("cities"); final cities = citiesRef .where("regions", arrayContainsAny: ["west_coast", "east_coast"]);
جافا
بايثون
Python
سي ++
CollectionReference cities_ref = db->Collection("cities"); cities_ref.WhereArrayContainsAny("region", std::vector<FieldValue> { FieldValue::String("west_coast"), FieldValue::String("east_coast") });
Node.js
يذهب
بي أتش بي
وحدة
Query query = citiesRef.WhereArrayContainsAny( "regions", new List<object>() { new List<object>(){"west_coast"}, new List<object>(){"east_coast"}});
ج #
روبي
يقوم هذا الاستعلام بإرجاع كل مستند مدينة حيث يكون حقل regions
عبارة عن مصفوفة تحتوي على west_coast
أو east_coast
. من بيانات المثال، يتضمن ذلك مستندات SF
و LA
و DC
.
يتم إلغاء خداع النتائج من array-contains-any
. حتى إذا كان حقل صفيف المستند يطابق أكثر من واحدة من قيم المقارنة، فإن مجموعة النتائج تتضمن هذا المستند مرة واحدة فقط.
array-contains-any
مرشحات دائمًا حسب نوع بيانات المصفوفة. على سبيل المثال، لن يُرجع الاستعلام أعلاه مستند مدينة حيث يكون حقل regions
هو السلسلة west_coast
بدلاً من المصفوفة.
يمكنك استخدام قيمة مصفوفة كقيمة مقارنة لـ in
، ولكن على عكس array-contains-any
، فإن الجملة تتطابق تمامًا مع طول المصفوفة وترتيبها وقيمها. على سبيل المثال:
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where('regions', 'in', [['west_coast'], ['east_coast']]));
Web namespaced API
citiesRef.where('regions', 'in', [['west_coast'], ['east_coast']]);
سويفت
citiesRef.whereField("regions", in: [["west_coast"], ["east_coast"]])
ج موضوعية
[citiesRef queryWhereField:@"regions" in:@[@[@"west_coast"], @[@"east_coast"]]];
Kotlin+KTX
citiesRef.whereIn("regions", listOf(arrayOf("west_coast"), arrayOf("east_coast")))
Java
citiesRef.whereIn("regions", Arrays.asList(new String[]{"west_coast"}, new String[]{"east_coast"}));
Dart
final citiesRef = db.collection("cities"); final cities = citiesRef.where("regions", whereIn: [ ["west_coast"], ["east_coast"] ]);
جافا
بايثون
Python
سي ++
cities_ref.WhereIn("region", std::vector<FieldValue> { FieldValue::String("west_coast"), FieldValue::String("east_coast") });
Node.js
يذهب
بي أتش بي
وحدة
Query query = citiesRef.WhereIn(new FieldPath("regions"), new List<string>{"west_coast", "east_coast"});
ج #
روبي
يقوم هذا الاستعلام بإرجاع كل مستند مدينة حيث يكون حقل regions
عبارة عن مصفوفة تحتوي بالضبط على عنصر واحد من west_coast
أو east_coast
. من بيانات المثال، مستند DC
فقط هو المؤهل بحقل regions
الخاص به ["east_coast"]
. ومع ذلك، فإن مستند SF
غير متطابق لأن حقل regions
الخاص به هو ["west_coast", "norcal"]
.
محددات
لاحظ القيود التالية لـ in
و not-in
و array-contains-any
:
- يوفر Cloud Firestore الدعم للاستعلامات المنطقية
OR
من خلال عوامل تشغيلor
in
وarray-contains-any
. تقتصر هذه الاستعلامات على 30 فصلًا استنادًا إلى النموذج العادي المنفصل للاستعلام . - يمكنك استخدام
array-contains
واحد على الأكثر لكل انفصال (or
مجموعة). لا يمكنك دمجarray-contains
علىarray-contains-any
في نفس الانفصال. - لا يمكنك الجمع بين
not-in
و not يساوي!=
. -
not-in
يدعم ما يصل إلى 10 قيم مقارنة.
الاستعلامات المركبة ( AND
).
يمكنك دمج القيود مع منطقية AND
عن طريق تسلسل عوامل المساواة المتعددة ( ==
أو array-contains
). ومع ذلك، يجب عليك إنشاء فهرس مركب لدمج عوامل المساواة مع عوامل عدم المساواة، <
و <=
و >
و !=
.
Web modular API
import { query, where } from "firebase/firestore"; const q1 = query(citiesRef, where("state", "==", "CO"), where("name", "==", "Denver")); const q2 = query(citiesRef, where("state", "==", "CA"), where("population", "<", 1000000));
Web namespaced API
const q1 = citiesRef.where("state", "==", "CO").where("name", "==", "Denver"); const q2 = citiesRef.where("state", "==", "CA").where("population", "<", 1000000);
سويفت
citiesRef .whereField("state", isEqualTo: "CO") .whereField("name", isEqualTo: "Denver") citiesRef .whereField("state", isEqualTo: "CA") .whereField("population", isLessThan: 1000000)
ج موضوعية
[[citiesRef queryWhereField:@"state" isEqualTo:@"CO"] queryWhereField:@"name" isGreaterThanOrEqualTo:@"Denver"]; [[citiesRef queryWhereField:@"state" isEqualTo:@"CA"] queryWhereField:@"population" isLessThan:@1000000];
Kotlin+KTX
citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver") citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000)
Java
citiesRef.whereEqualTo("state", "CO").whereEqualTo("name", "Denver"); citiesRef.whereEqualTo("state", "CA").whereLessThan("population", 1000000);
Dart
final citiesRef = db.collection("cities"); citiesRef .where("state", isEqualTo: "CO") .where("name", isEqualTo: "Denver"); citiesRef .where("state", isEqualTo: "CA") .where("population", isLessThan: 1000000);
جافا
بايثون
Python
سي ++
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
يذهب
بي أتش بي
وحدة
Query chainedQuery = citiesRef .WhereEqualTo("State", "CA") .WhereEqualTo("Name", "San Francisco");
ج #
روبي
يمكنك إجراء مقارنات بين النطاق ( <
, <=
, >
, >=
) أو لا يساوي ( !=
) في حقل واحد فقط، ويمكنك تضمين array-contains
أو array-contains-any
في استعلام مركب :
صالح : نطاق المرشحات في حقل واحد فقط
Web modular API
import { query, where } from "firebase/firestore"; const q1 = query(citiesRef, where("state", ">=", "CA"), where("state", "<=", "IN")); const q2 = query(citiesRef, where("state", "==", "CA"), where("population", ">", 1000000));
Web namespaced API
const q1 = citiesRef.where("state", ">=", "CA").where("state", "<=", "IN"); const q2 = citiesRef.where("state", "==", "CA").where("population", ">", 1000000);
سويفت
citiesRef .whereField("state", isGreaterThanOrEqualTo: "CA") .whereField("state", isLessThanOrEqualTo: "IN") citiesRef .whereField("state", isEqualTo: "CA") .whereField("population", isGreaterThan: 1000000)
ج موضوعية
[[citiesRef queryWhereField:@"state" isGreaterThanOrEqualTo:@"CA"] queryWhereField:@"state" isLessThanOrEqualTo:@"IN"]; [[citiesRef queryWhereField:@"state" isEqualTo:@"CA"] queryWhereField:@"population" isGreaterThan:@1000000];
Kotlin+KTX
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereLessThanOrEqualTo("state", "IN") citiesRef.whereEqualTo("state", "CA") .whereGreaterThan("population", 1000000)
Java
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereLessThanOrEqualTo("state", "IN"); citiesRef.whereEqualTo("state", "CA") .whereGreaterThan("population", 1000000);
Dart
final citiesRef = db.collection("cities"); citiesRef .where("state", isGreaterThanOrEqualTo: "CA") .where("state", isLessThanOrEqualTo: "IN"); citiesRef .where("state", isEqualTo: "CA") .where("population", isGreaterThan: 1000000);
جافا
بايثون
Python
سي ++
cities_ref.WhereGreaterThanOrEqualTo("state", FieldValue::String("CA")) .WhereLessThanOrEqualTo("state", FieldValue::String("IN")); cities_ref.WhereEqualTo("state", FieldValue::String("CA")) .WhereGreaterThan("population", FieldValue::Integer(1000000));
Node.js
يذهب
بي أتش بي
وحدة
Query rangeQuery = citiesRef .WhereGreaterThanOrEqualTo("State", "CA") .WhereLessThanOrEqualTo("State", "IN");
ج #
روبي
غير صالح : نطاق عوامل التصفية في حقول مختلفة
Web modular API
import { query, where } from "firebase/firestore"; const q = query(citiesRef, where("state", ">=", "CA"), where("population", ">", 100000));
Web namespaced API
citiesRef.where("state", ">=", "CA").where("population", ">", 100000);
سويفت
citiesRef .whereField("state", isGreaterThanOrEqualTo: "CA") .whereField("population", isGreaterThan: 1000000)
ج موضوعية
[[citiesRef queryWhereField:@"state" isGreaterThanOrEqualTo:@"CA"] queryWhereField:@"population" isGreaterThan:@1000000];
Kotlin+KTX
citiesRef.whereGreaterThanOrEqualTo("state", "CA") .whereGreaterThan("population", 100000)
Java
citiesRef.whereGreaterThanOrEqualTo("state", "CA").whereGreaterThan("population", 100000);
Dart
final citiesRef = db.collection("cities"); citiesRef .where("state", isGreaterThanOrEqualTo: "CA") .where("population", isGreaterThan: 1000000);
جافا
بايثون
Python
سي ++
// BAD EXAMPLE -- will crash the program: cities_ref.WhereGreaterThanOrEqualTo("state", FieldValue::String("CA")) .WhereGreaterThan("population", FieldValue::Integer(100000));
Node.js
يذهب
بي أتش بي
وحدة
Query invalidRangeQuery = citiesRef .WhereGreaterThanOrEqualTo("State", "CA") .WhereGreaterThan("Population", 1000000);
ج #
روبي
OR
الاستعلامات
يمكنك دمج القيود مع OR
المنطقي. على سبيل المثال:
Web modular API
const q = query(citiesRef, or(where('capital', '==', true), where('population', '>=', 1000000) ) );
Web namespaced API
غير متاح.
سويفت
let query = db.collection("cities").whereFilter(Filter.orFilter([ Filter.whereField("capital", isEqualTo: true), Filter.whereField("population", isGreaterThanOrEqualTo: 1000000); ]))
ج موضوعية
FIRCollectionReference *collection = [self.db collectionWithPath:@"cities"]; FIRQuery *query = [collection queryWhereFilter:[FIRFilter orFilterWithFilters:@[ [FIRFilter filterWhereField:@"capital" isEqualTo:@YES], [FIRFilter filterWhereField:@"population" isGreaterThanOrEqualTo:@1000000] ]]];
Kotlin+KTX
val query = collection.where(Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ))
Java
Query query = collection.where(Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ));
Dart
var query = db.collection("cities") .where( Filter.or( Filter("capital", isEqualTo: true), Filter("population", isGreaterThan: 1000000) ));
جافا
المقتطف غير متوفر.
بايثون
Python
المقتطف غير متوفر.
سي ++
المقتطف غير متوفر.
Node.js
const bigCities = await citiesRef .where( Filter.or( Filter.where('capital', '==', true), Filter.where('population', '>=', 1000000) ) ) .get();
يذهب
بي أتش بي
المقتطف غير متوفر.
وحدة
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)); } });
ج #
المقتطف غير متوفر.
روبي
المقتطف غير متوفر.
يستخدم Cloud Firestore الفهارس المركبة الخاصة بك لخدمة OR
الاستعلامات. إذا كانت الفهارس الخاصة بك لا تدعم الاستعلام، فإن Cloud Firestore يقترح فهارس إضافية لقاعدة البيانات الخاصة بك .
يمكنك دمج استعلامات OR
مع الاستعلامات المركبة للتصفية على مجموعات من عمليات OR
و AND
. على سبيل المثال:
Web modular API
const q = query(collection(db, "cities"), and( where('state', '==', 'CA'), or( where('capital', '==', true), where('population', '>=', 1000000) ) ));
Web namespaced API
غير متاح.
سويفت
let query = db.collection("cities").whereFilter(Filter.andFilter([ Filter.whereField("state", isEqualTo: "CA"), Filter.orFilter([ Filter.whereField("capital", isEqualTo: true), Filter.whereField("population", isGreaterThanOrEqualTo: 1000000); ]) ]))
ج موضوعية
FIRCollectionReference *collection = [self.db collectionWithPath:@"cities"]; FIRQuery *query = [collection queryWhereFilter:[FIRFilter andFilterWithFilters:@[ [FIRFilter filterWhereField:@"state" isEqualTo:@"CA"], [FIRFilter orFilterWithFilters:@[ [FIRFilter filterWhereField:@"capital" isEqualTo:@YES], [FIRFilter filterWhereField:@"population" isGreaterThanOrEqualTo:@1000000] ]] ]]];
Kotlin+KTX
val query = collection.where(Filter.and( Filter.equalTo("state", "CA"), Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ) ))
Java
Query query = collection.where(Filter.and( Filter.equalTo("state", "CA"), Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ) ));
Dart
var query = db.collection("cities") .where( Filter.and( Filter("state", isEqualTo: "CA"), Filter.or( Filter("capital", isEqualTo: true), Filter("population", isGreaterThan: 1000000) )));
جافا
المقتطف غير متوفر.
بايثون
المقتطف غير متوفر.
Python
المقتطف غير متوفر.
سي ++
المقتطف غير متوفر.
Node.js
const bigCitiesInCalifornia = await citiesRef .where('state', '==', 'CA') .where( Filter.or( Filter.where('capital', '==', true), Filter.where('population', '>=', 1000000) ) ) .get();
يذهب
المقتطف غير متوفر.
بي أتش بي
المقتطف غير متوفر.
وحدة
Query query = citiesRef.Where(Filter.And( Filter.EqualTo("state", "CA"), Filter.Or( Filter.EqualTo("capital", true), Filter.GreaterThanOrEqualTo("population", 1000000) ) ));
ج #
المقتطف غير متوفر.
روبي
المقتطف غير متوفر.
محددات
لاحظ القيود التالية or
الاستعلامات:
- يحد Cloud Firestore من الاستعلام بحد أقصى 30 فصلًا بناءً على النموذج العادي المنفصل للاستعلام . من المرجح أن تصل إلى هذا الحد عند إجراء
AND
لعدة مجموعاتOR
. - لا يمكنك دمج
not-in
معin
أوarray-contains-any
أوor
في نفس الاستعلام.
للحصول على وصف كامل للقيود، راجع قيود الاستعلام .
استعلامات مجموعة المجموعة
تتكون مجموعة المجموعة من كافة المجموعات التي لها نفس المعرف. بشكل افتراضي، تقوم الاستعلامات باسترداد النتائج من مجموعة واحدة في قاعدة البيانات الخاصة بك. استخدم استعلام مجموعة مجموعة لاسترداد المستندات من مجموعة مجموعة بدلاً من مجموعة واحدة.
على سبيل المثال، يمكنك إنشاء مجموعة مجموعة landmarks
عن طريق إضافة مجموعة معالم فرعية لكل مدينة:
Web modular API
import { collection, addDoc } from "firebase/firestore"; const citiesRef = collection(db, 'cities'); await Promise.all([ addDoc(collection(citiesRef, 'SF', 'landmarks'), { name: 'Golden Gate Bridge', type: 'bridge' }), addDoc(collection(citiesRef, 'SF', 'landmarks'), { name: 'Legion of Honor', type: 'museum' }), addDoc(collection(citiesRef, 'LA', 'landmarks'), { name: 'Griffith Park', type: 'park' }), addDoc(collection(citiesRef, 'LA', 'landmarks'), { name: 'The Getty', type: 'museum' }), addDoc(collection(citiesRef, 'DC', 'landmarks'), { name: 'Lincoln Memorial', type: 'memorial' }), addDoc(collection(citiesRef, 'DC', 'landmarks'), { name: 'National Air and Space Museum', type: 'museum' }), addDoc(collection(citiesRef, 'TOK', 'landmarks'), { name: 'Ueno Park', type: 'park' }), addDoc(collection(citiesRef, 'TOK', 'landmarks'), { name: 'National Museum of Nature and Science', type: 'museum' }), addDoc(collection(citiesRef, 'BJ', 'landmarks'), { name: 'Jingshan Park', type: 'park' }), addDoc(collection(citiesRef, 'BJ', 'landmarks'), { name: 'Beijing Ancient Observatory', type: 'museum' }) ]);
Web namespaced API
var citiesRef = db.collection('cities'); var landmarks = Promise.all([ citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Golden Gate Bridge', type: 'bridge' }), citiesRef.doc('SF').collection('landmarks').doc().set({ name: 'Legion of Honor', type: 'museum' }), citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'Griffith Park', type: 'park' }), citiesRef.doc('LA').collection('landmarks').doc().set({ name: 'The Getty', type: 'museum' }), citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'Lincoln Memorial', type: 'memorial' }), citiesRef.doc('DC').collection('landmarks').doc().set({ name: 'National Air and Space Museum', type: 'museum' }), citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'Ueno Park', type: 'park' }), citiesRef.doc('TOK').collection('landmarks').doc().set({ name: 'National Museum of Nature and Science', type: 'museum' }), citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Jingshan Park', type: 'park' }), citiesRef.doc('BJ').collection('landmarks').doc().set({ name: 'Beijing Ancient Observatory', type: 'museum' }) ]);
سويفت
let citiesRef = db.collection("cities") var data = ["name": "Golden Gate Bridge", "type": "bridge"] citiesRef.document("SF").collection("landmarks").addDocument(data: data) data = ["name": "Legion of Honor", "type": "museum"] citiesRef.document("SF").collection("landmarks").addDocument(data: data) data = ["name": "Griffith Park", "type": "park"] citiesRef.document("LA").collection("landmarks").addDocument(data: data) data = ["name": "The Getty", "type": "museum"] citiesRef.document("LA").collection("landmarks").addDocument(data: data) data = ["name": "Lincoln Memorial", "type": "memorial"] citiesRef.document("DC").collection("landmarks").addDocument(data: data) data = ["name": "National Air and Space Museum", "type": "museum"] citiesRef.document("DC").collection("landmarks").addDocument(data: data) data = ["name": "Ueno Park", "type": "park"] citiesRef.document("TOK").collection("landmarks").addDocument(data: data) data = ["name": "National Museum of Nature and Science", "type": "museum"] citiesRef.document("TOK").collection("landmarks").addDocument(data: data) data = ["name": "Jingshan Park", "type": "park"] citiesRef.document("BJ").collection("landmarks").addDocument(data: data) data = ["name": "Beijing Ancient Observatory", "type": "museum"] citiesRef.document("BJ").collection("landmarks").addDocument(data: data)
ج موضوعية
FIRCollectionReference *citiesRef = [self.db collectionWithPath:@"cities"]; NSDictionary *data = @{@"name": @"Golden Gate Bridge", @"type": @"bridge"}; [[[citiesRef documentWithPath:@"SF"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Legion of Honor", @"type": @"museum"}; [[[citiesRef documentWithPath:@"SF"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Griffith Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"LA"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"The Getty", @"type": @"museum"}; [[[citiesRef documentWithPath:@"LA"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Lincoln Memorial", @"type": @"memorial"}; [[[citiesRef documentWithPath:@"DC"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"National Air and Space Museum", @"type": @"museum"}; [[[citiesRef documentWithPath:@"DC"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Ueno Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"TOK"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"National Museum of Nature and Science", @"type": @"museum"}; [[[citiesRef documentWithPath:@"TOK"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Jingshan Park", @"type": @"park"}; [[[citiesRef documentWithPath:@"BJ"] collectionWithPath:@"landmarks"] addDocumentWithData:data]; data = @{@"name": @"Beijing Ancient Observatory", @"type": @"museum"}; [[[citiesRef documentWithPath:@"BJ"] collectionWithPath:@"landmarks"] addDocumentWithData:data];
Kotlin+KTX
val citiesRef = db.collection("cities") val ggbData = mapOf( "name" to "Golden Gate Bridge", "type" to "bridge", ) citiesRef.document("SF").collection("landmarks").add(ggbData) val lohData = mapOf( "name" to "Legion of Honor", "type" to "museum", ) citiesRef.document("SF").collection("landmarks").add(lohData) val gpData = mapOf( "name" to "Griffth Park", "type" to "park", ) citiesRef.document("LA").collection("landmarks").add(gpData) val tgData = mapOf( "name" to "The Getty", "type" to "museum", ) citiesRef.document("LA").collection("landmarks").add(tgData) val lmData = mapOf( "name" to "Lincoln Memorial", "type" to "memorial", ) citiesRef.document("DC").collection("landmarks").add(lmData) val nasaData = mapOf( "name" to "National Air and Space Museum", "type" to "museum", ) citiesRef.document("DC").collection("landmarks").add(nasaData) val upData = mapOf( "name" to "Ueno Park", "type" to "park", ) citiesRef.document("TOK").collection("landmarks").add(upData) val nmData = mapOf( "name" to "National Musuem of Nature and Science", "type" to "museum", ) citiesRef.document("TOK").collection("landmarks").add(nmData) val jpData = mapOf( "name" to "Jingshan Park", "type" to "park", ) citiesRef.document("BJ").collection("landmarks").add(jpData) val baoData = mapOf( "name" to "Beijing Ancient Observatory", "type" to "musuem", ) citiesRef.document("BJ").collection("landmarks").add(baoData)
Java
CollectionReference citiesRef = db.collection("cities"); Map<String, Object> ggbData = new HashMap<>(); ggbData.put("name", "Golden Gate Bridge"); ggbData.put("type", "bridge"); citiesRef.document("SF").collection("landmarks").add(ggbData); Map<String, Object> lohData = new HashMap<>(); lohData.put("name", "Legion of Honor"); lohData.put("type", "museum"); citiesRef.document("SF").collection("landmarks").add(lohData); Map<String, Object> gpData = new HashMap<>(); gpData.put("name", "Griffith Park"); gpData.put("type", "park"); citiesRef.document("LA").collection("landmarks").add(gpData); Map<String, Object> tgData = new HashMap<>(); tgData.put("name", "The Getty"); tgData.put("type", "museum"); citiesRef.document("LA").collection("landmarks").add(tgData); Map<String, Object> lmData = new HashMap<>(); lmData.put("name", "Lincoln Memorial"); lmData.put("type", "memorial"); citiesRef.document("DC").collection("landmarks").add(lmData); Map<String, Object> nasaData = new HashMap<>(); nasaData.put("name", "National Air and Space Museum"); nasaData.put("type", "museum"); citiesRef.document("DC").collection("landmarks").add(nasaData); Map<String, Object> upData = new HashMap<>(); upData.put("name", "Ueno Park"); upData.put("type", "park"); citiesRef.document("TOK").collection("landmarks").add(upData); Map<String, Object> nmData = new HashMap<>(); nmData.put("name", "National Museum of Nature and Science"); nmData.put("type", "museum"); citiesRef.document("TOK").collection("landmarks").add(nmData); Map<String, Object> jpData = new HashMap<>(); jpData.put("name", "Jingshan Park"); jpData.put("type", "park"); citiesRef.document("BJ").collection("landmarks").add(jpData); Map<String, Object> baoData = new HashMap<>(); baoData.put("name", "Beijing Ancient Observatory"); baoData.put("type", "museum"); citiesRef.document("BJ").collection("landmarks").add(baoData);
Dart
final citiesRef = db.collection("cities"); final ggbData = {"name": "Golden Gate Bridge", "type": "bridge"}; citiesRef.doc("SF").collection("landmarks").add(ggbData); final lohData = {"name": "Legion of Honor", "type": "museum"}; citiesRef.doc("SF").collection("landmarks").add(lohData); final gpData = {"name": "Griffth Park", "type": "park"}; citiesRef.doc("LA").collection("landmarks").add(gpData); final tgData = {"name": "The Getty", "type": "museum"}; citiesRef.doc("LA").collection("landmarks").add(tgData); final lmData = {"name": "Lincoln Memorial", "type": "memorial"}; citiesRef.doc("DC").collection("landmarks").add(lmData); final nasaData = { "name": "National Air and Space Museum", "type": "museum" }; citiesRef.doc("DC").collection("landmarks").add(nasaData); final upData = {"name": "Ueno Park", "type": "park"}; citiesRef.doc("TOK").collection("landmarks").add(upData); final nmData = { "name": "National Musuem of Nature and Science", "type": "museum" }; citiesRef.doc("TOK").collection("landmarks").add(nmData); final jpData = {"name": "Jingshan Park", "type": "park"}; citiesRef.doc("BJ").collection("landmarks").add(jpData); final baoData = {"name": "Beijing Ancient Observatory", "type": "musuem"}; citiesRef.doc("BJ").collection("landmarks").add(baoData);
جافا
بايثون
Python
سي ++
// 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
يذهب
بي أتش بي
وحدة
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;
ج #
روبي
يمكننا استخدام الاستعلام البسيط والمركب الموضح سابقًا للاستعلام عن المجموعة landmarks
مدينة واحدة، ولكن قد ترغب أيضًا في استرداد النتائج من المجموعة landmarks
كل مدينة مرة واحدة.
تتكون مجموعة مجموعة landmarks
من جميع المجموعات ذات معرف landmarks
، ويمكنك الاستعلام عنها باستخدام استعلام مجموعة المجموعة. على سبيل المثال، يسترد استعلام مجموعة المجموعة هذا جميع معالم museum
في جميع المدن:
Web modular API
import { collectionGroup, query, where, getDocs } from "firebase/firestore"; const museums = query(collectionGroup(db, 'landmarks'), where('type', '==', 'museum')); const querySnapshot = await getDocs(museums); querySnapshot.forEach((doc) => { console.log(doc.id, ' => ', doc.data()); });
Web namespaced API
var museums = db.collectionGroup('landmarks').where('type', '==', 'museum'); museums.get().then((querySnapshot) => { querySnapshot.forEach((doc) => { console.log(doc.id, ' => ', doc.data()); }); });
سويفت
db.collectionGroup("landmarks").whereField("type", isEqualTo: "museum").getDocuments { (snapshot, error) in // ... }
ج موضوعية
[[[self.db collectionGroupWithID:@"landmarks"] queryWhereField:@"type" isEqualTo:@"museum"] getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) { // ... }];
Kotlin+KTX
db.collectionGroup("landmarks").whereEqualTo("type", "museum").get() .addOnSuccessListener { queryDocumentSnapshots -> // ... }
Java
db.collectionGroup("landmarks").whereEqualTo("type", "museum").get() .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() { @Override public void onSuccess(QuerySnapshot queryDocumentSnapshots) { // ... } });
Dart
db .collectionGroup("landmarks") .where("type", isEqualTo: "museum") .get() .then( (res) => print("Successfully completed"), onError: (e) => print("Error completing: $e"), );
جافا
بايثون
Python
سي ++
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
يذهب
بي أتش بي
وحدة
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)); } });
ج #
روبي
قبل استخدام استعلام مجموعة المجموعة، يجب عليك إنشاء فهرس يدعم استعلام مجموعة المجموعة الخاصة بك. يمكنك إنشاء فهرس من خلال رسالة خطأ أو وحدة التحكم أو Firebase CLI .
بالنسبة لمجموعات SDK للويب والجوال، يجب عليك أيضًا إنشاء قواعد تسمح باستعلامات مجموعة المجموعة الخاصة بك .
قيود الاستعلام
تلخص القائمة التالية قيود استعلام Cloud Firestore:
- يوفر Cloud Firestore الدعم للاستعلامات المنطقية
OR
من خلال عوامل تشغيلor
in
وarray-contains-any
. تقتصر هذه الاستعلامات على 30 فصلًا استنادًا إلى النموذج العادي المنفصل للاستعلام . - في الاستعلام المركب، يجب تصفية مقارنات النطاق (
<
,<=
,>
,>=
) وليس يساوي (!=
,not-in
) في نفس الحقل. - يمكنك استخدام
array-contains
واحد على الأكثر لكل انفصال (or
مجموعة). لا يمكنك دمجarray-contains
علىarray-contains-any
في نفس الانفصال. - لا يمكنك دمج
not-in
معin
أوarray-contains-any
أوor
في نفس الاستعلام. - يُسمح فقط
not-in
أو!=
` لكل استعلام. -
not-in
يدعم ما يصل إلى 10 قيم مقارنة. - لا يمكن أن يتجاوز مجموع عوامل التصفية وأوامر الفرز ومسار المستند الأصلي (1 للمجموعة الفرعية، 0 للمجموعة الجذرية) في الاستعلام 100. ويتم حساب ذلك بناءً على النموذج العادي المنفصل للاستعلام .
- يشير الاستعلام الذي يحتوي على عامل تصفية عدم المساواة في أحد الحقول إلى الترتيب حسب هذا الحقل وعوامل التصفية لوجود هذا الحقل .
حدود استعلامات OR
لمنع أن يصبح الاستعلام مكلفًا للغاية من الناحية الحسابية، يحد Cloud Firestore من عدد عبارات AND
و OR
التي يمكنك دمجها. لتطبيق هذا الحد، يقوم Cloud Firestore بتحويل الاستعلامات التي تنفذ عمليات OR
المنطقية ( or
, in
, و array-contains-any
) إلى نموذج عادي منفصل (يُعرف أيضًا باسم OR
لـ AND
s). يحد Cloud Firestore من الاستعلام بحد أقصى 30 انفصالًا في النموذج العادي المنفصل.
الشكل العادي المنفصل
يقوم Cloud Firestore بتحويل الاستعلامات إلى نموذج عادي منفصل من خلال تطبيق قاعدتين:
تتسطح
بالنظر إلى الشروط
A
،B
،C
:A and (B and C) => A and B and C
بالنظر إلى الشروط
A
،B
،C
،D
:-
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)
-
عند تطبيق هذه القواعد in
array-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
والوجود
عندما تقوم بترتيب استعلام حسب حقل معين، يمكن للاستعلام إرجاع المستندات التي يوجد بها حقل الترتيب حسب فقط.
على سبيل المثال، لن يقوم الاستعلام التالي بإرجاع أي مستندات لم يتم تعيين حقل population
فيها، حتى لو كانت تتوافق مع عوامل تصفية الاستعلام.
جافا
db.collection("cities").whereEqualTo("country", “USA”).orderBy(“population”);
وينطبق تأثير ذو صلة على عدم المساواة. يتضمن الاستعلام الذي يحتوي على عامل تصفية عدم المساواة في الحقل أيضًا الترتيب حسب هذا الحقل. لا يقوم الاستعلام التالي بإرجاع المستندات التي لا تحتوي على حقل population
حتى لو كانت country = USA
في تلك الوثيقة. كحل بديل، يمكنك تنفيذ استعلامات منفصلة لكل طلب أو يمكنك تعيين قيمة لجميع الحقول التي تطلب بها.
جافا
db.collection(“cities”).where(or(“country”, USA”), greaterThan(“population”, 250000));
يتضمن الاستعلام أعلاه ترتيبًا ضمنيًا للمتباينة ويعادل ما يلي:
جافا
db.collection(“cities”).where(or(“country”, USA”), greaterThan(“population”, 250000)).orderBy(“population”);
ماذا بعد
- تعرف على كيفية ترتيب البيانات والحد منها في نتائج الاستعلام .
- حفظ ما يقرأ عندما تريد ببساطة حساب النتائج .