Thông tin khái quát
Các hoạt động của quy trình cung cấp một giao diện truy vấn mới cho
Cloud Firestore hỗ trợ chức năng truy vấn nâng cao và các biểu thức phức tạp. Giao diện này giới thiệu nhiều hàm mới, bao gồm min(...), max(...), substring(...), regex_match(...) và array_contains_all(...), cũng như các giai đoạn để có thể thực hiện các phép biến đổi phức tạp.
Bắt đầu
Để cài đặt và khởi chạy SDK ứng dụng, hãy tham khảo hướng dẫn trong các bài viết sau:
Cú pháp
Các phần sau đây cung cấp thông tin tổng quan về cú pháp cho các hoạt động của quy trình.
Khái niệm
Một điểm khác biệt đáng chú ý với các hoạt động của quy trình là việc giới thiệu thứ tự "giai đoạn" rõ ràng. Điều này giúp bạn có thể biểu thị các truy vấn phức tạp hơn. Tuy nhiên, đây là một điểm khác biệt đáng chú ý so với giao diện truy vấn hiện có bằng cách sử dụng các hoạt động cốt lõi, trong đó thứ tự của các giai đoạn được ngụ ý. Hãy xem ví dụ sau về các hoạt động của quy trình:
Web
const pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the // pipeline would have unintentional results. .limit(10);
Swift
let pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(Field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort([Field("name").ascending()]) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10)
Kotlin
val pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10)
Java
Pipeline pipeline = db.pipeline() // Step 1: Start a query with collection scope .collection("cities") // Step 2: Filter the collection .where(field("population").greaterThan(100000)) // Step 3: Sort the remaining documents .sort(field("name").ascending()) // Step 4: Return the top 10. Note applying the limit earlier in the pipeline would have // unintentional results. .limit(10);
Python
from google.cloud.firestore_v1.pipeline_expressions import Field pipeline = ( client.pipeline() .collection("cities") .where(Field.of("population").greater_than(100_000)) .sort(Field.of("name").ascending()) .limit(10) )
Khởi chạy
Các hoạt động của quy trình có một cú pháp rất quen thuộc đến từ các truy vấn Cloud Firestore hiện có. Để bắt đầu, bạn hãy khởi chạy một truy vấn bằng cách viết như sau:
Web
const { getFirestore } = require("firebase/firestore"); const { execute } = require("firebase/firestore/pipelines"); const database = getFirestore(app, "enterprise"); const pipeline = database.pipeline();
Swift
let firestore = Firestore.firestore(database: "enterprise") let pipeline = firestore.pipeline()
Kotlin
val firestore = Firebase.firestore("enterprise") val pipeline = firestore.pipeline()
Java
FirebaseFirestore firestore = FirebaseFirestore.getInstance("enterprise"); PipelineSource pipeline = firestore.pipeline();
Python
firestore_client = firestore.client(default_app, "your-new-enterprise-database") pipeline = firestore_client.pipeline()
Cấu trúc
Có một vài thuật ngữ quan trọng mà bạn cần hiểu khi tạo các hoạt động của quy trình: giai đoạn, biểu thức và hàm.

Giai đoạn: Một quy trình có thể bao gồm một hoặc nhiều giai đoạn. Về mặt logic, các giai đoạn này đại diện cho chuỗi các bước (hoặc giai đoạn) được thực hiện để thực thi truy vấn. Lưu ý: Trong thực tế, các giai đoạn có thể được thực thi không theo thứ tự để cải thiện hiệu suất. Tuy nhiên, điều này không làm thay đổi ý định hoặc tính chính xác của truy vấn.
Biểu thức: Các giai đoạn thường chấp nhận một biểu thức cho phép bạn biểu thị các truy vấn phức tạp hơn. Biểu thức có thể đơn giản và bao gồm một hàm duy nhất như eq("a", 1). Bạn cũng có thể biểu thị các biểu thức phức tạp hơn bằng cách lồng các biểu thức như and(eq("a", 1), eq("b", 2)).
Tham chiếu trường so với tham chiếu hằng số
Các hoạt động của quy trình hỗ trợ các biểu thức phức tạp. Do đó, bạn có thể cần phân biệt xem một giá trị đại diện cho trường hay hằng số. Hãy xem ví dụ sau đây:
Web
const pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")));
Swift
let pipeline = db.pipeline() .collection("cities") .where(Field("name").equal(Constant("Toronto")))
Kotlin
val pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")))
Java
Pipeline pipeline = db.pipeline() .collection("cities") .where(field("name").equal(constant("Toronto")));
Python
from google.cloud.firestore_v1.pipeline_expressions import Field, Constant pipeline = ( client.pipeline() .collection("cities") .where(Field.of("name").equal(Constant.of("Toronto"))) )
Giai đoạn
Giai đoạn đầu vào
Giai đoạn đầu vào đại diện cho giai đoạn đầu tiên của một truy vấn. Giai đoạn này xác định tập hợp tài liệu ban đầu mà bạn đang truy vấn. Đối với các hoạt động của quy trình, điều này phần lớn tương tự như các truy vấn hiện có, trong đó hầu hết các truy vấn bắt đầu bằng giai đoạn collection(...) hoặc collection_group(...). Hai giai đoạn đầu vào mới là database() và documents(...), trong đó database() cho phép trả về tất cả tài liệu trong cơ sở dữ liệu, còn documents(...) hoạt động giống như một lần đọc hàng loạt.
Web
let results; // Return all restaurants in San Francisco results = await execute(db.pipeline().collection("cities/sf/restaurants")); // Return all restaurants results = await execute(db.pipeline().collectionGroup("restaurants")); // Return all documents across all collections in the database (the entire database) results = await execute(db.pipeline().database()); // Batch read of 3 documents results = await execute(db.pipeline().documents([ doc(db, "cities", "SF"), doc(db, "cities", "DC"), doc(db, "cities", "NY") ]));
Swift
var results: Pipeline.Snapshot // Return all restaurants in San Francisco results = try await db.pipeline().collection("cities/sf/restaurants").execute() // Return all restaurants results = try await db.pipeline().collectionGroup("restaurants").execute() // Return all documents across all collections in the database (the entire database) results = try await db.pipeline().database().execute() // Batch read of 3 documents results = try await db.pipeline().documents([ db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ]).execute()
Kotlin
var results: Task<Pipeline.Snapshot> // Return all restaurants in San Francisco results = db.pipeline().collection("cities/sf/restaurants").execute() // Return all restaurants results = db.pipeline().collectionGroup("restaurants").execute() // Return all documents across all collections in the database (the entire database) results = db.pipeline().database().execute() // Batch read of 3 documents results = db.pipeline().documents( db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ).execute()
Java
Task<Pipeline.Snapshot> results; // Return all restaurants in San Francisco results = db.pipeline().collection("cities/sf/restaurants").execute(); // Return all restaurants results = db.pipeline().collectionGroup("restaurants").execute(); // Return all documents across all collections in the database (the entire database) results = db.pipeline().database().execute(); // Batch read of 3 documents results = db.pipeline().documents( db.collection("cities").document("SF"), db.collection("cities").document("DC"), db.collection("cities").document("NY") ).execute();
Python
# Return all restaurants in San Francisco results = client.pipeline().collection("cities/sf/restaurants").execute() # Return all restaurants results = client.pipeline().collection_group("restaurants").execute() # Return all documents across all collections in the database (the entire database) results = client.pipeline().database().execute() # Batch read of 3 documents results = ( client.pipeline() .documents( client.collection("cities").document("SF"), client.collection("cities").document("DC"), client.collection("cities").document("NY"), ) .execute() )
Giống như tất cả các giai đoạn khác, thứ tự kết quả từ các giai đoạn đầu vào này không ổn định. Bạn phải luôn thêm toán tử sort(...) nếu muốn có một thứ tự cụ thể.
Địa điểm
Giai đoạn where(...) hoạt động như một thao tác lọc truyền thống trên các tài liệu được tạo từ giai đoạn trước và hầu hết phản ánh cú pháp "where" hiện có cho các truy vấn hiện có. Mọi tài liệu mà một biểu thức nhất định đánh giá thành giá trị không phải là true đều bị lọc ra khỏi các tài liệu được trả về.
Bạn có thể xâu chuỗi nhiều câu lệnh where(...) với nhau và hoạt động như một biểu thức and(...). Ví dụ: hai truy vấn sau đây tương đương về mặt logic và có thể được sử dụng thay thế cho nhau.
Web
let results; results = await execute(db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) ); results = await execute(db.pipeline().collection("books") .where(and(field("rating").equal(5), field("published").lessThan(1900))) );
Swift
var results: Pipeline.Snapshot results = try await db.pipeline().collection("books") .where(Field("rating").equal(5)) .where(Field("published").lessThan(1900)) .execute() results = try await db.pipeline().collection("books") .where(Field("rating").equal(5) && Field("published").lessThan(1900)) .execute()
Kotlin
var results: Task<Pipeline.Snapshot> results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute() results = db.pipeline().collection("books") .where(Expression.and(field("rating").equal(5), field("published").lessThan(1900))) .execute()
Java
Task<Pipeline.Snapshot> results; results = db.pipeline().collection("books") .where(field("rating").equal(5)) .where(field("published").lessThan(1900)) .execute(); results = db.pipeline().collection("books") .where(Expression.and( field("rating").equal(5), field("published").lessThan(1900) )) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import And, Field results = ( client.pipeline() .collection("books") .where(Field.of("rating").equal(5)) .where(Field.of("published").less_than(1900)) .execute() ) results = ( client.pipeline() .collection("books") .where(And(Field.of("rating").equal(5), Field.of("published").less_than(1900))) .execute() )
Chọn / Thêm và xoá trường
select(...), add_fields(...) và remove_fields(...) đều cho phép bạn sửa đổi các trường được trả về từ giai đoạn trước. Ba trường này thường được gọi là các giai đoạn theo kiểu chiếu.
select(...) và add_fields(...) cho phép bạn chỉ định kết quả của một biểu thức cho tên trường do người dùng cung cấp. Một biểu thức dẫn đến lỗi sẽ dẫn đến giá trị null. select(...) sẽ chỉ trả về các tài liệu có tên trường được chỉ định, trong khi add_fields(...) mở rộng giản đồ của giai đoạn trước (có thể ghi đè các giá trị có tên trường giống hệt nhau).
remove_fields(...) cho phép chỉ định một tập hợp các trường cần xoá khỏi giai đoạn trước. Việc chỉ định tên trường không tồn tại là một thao tác không có tác dụng.
Hãy xem phần Giới hạn các trường cần trả về bên dưới, nhưng nói chung, việc sử dụng một giai đoạn như vậy để giới hạn kết quả chỉ cho các trường cần thiết trong ứng dụng sẽ giúp giảm chi phí và độ trễ cho hầu hết các truy vấn.
Tổng hợp / Phân biệt
Giai đoạn aggregate(...) cho phép bạn thực hiện một loạt các phép tổng hợp trên các tài liệu đầu vào. Theo mặc định, tất cả các tài liệu được tổng hợp cùng nhau, nhưng bạn có thể cung cấp đối số grouping không bắt buộc, cho phép các tài liệu đầu vào được tổng hợp thành các nhóm khác nhau.
Web
const results = await execute(db.pipeline() .collection("books") .aggregate( field("rating").average().as("avg_rating") ) .distinct(field("genre")) );
Swift
let results = try await db.pipeline() .collection("books") .aggregate([ Field("rating").average().as("avg_rating") ], groups: [ Field("genre") ]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .aggregate( AggregateStage .withAccumulators(AggregateFunction.average("rating").alias("avg_rating")) .withGroups(field("genre")) ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .aggregate(AggregateStage .withAccumulators( AggregateFunction.average("rating").alias("avg_rating")) .withGroups(field("genre"))) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .aggregate( Field.of("rating").average().as_("avg_rating"), groups=[Field.of("genre")] ) .execute() )
Khi bạn không chỉ định groupings, giai đoạn này sẽ chỉ tạo một tài liệu duy nhất, nếu không, một tài liệu sẽ được tạo cho mỗi tổ hợp giá trị groupings riêng biệt.
Giai đoạn distinct(...) là một toán tử tổng hợp đơn giản cho phép chỉ tạo groupings riêng biệt mà không có bất kỳ bộ tích luỹ nào. Giai đoạn này hoạt động giống hệt như aggregate(...) về mọi mặt khác. Dưới đây là một ví dụ:
Web
const results = await execute(db.pipeline() .collection("books") .distinct( field("author").toUpper().as("author"), field("genre") ) );
Swift
let results = try await db.pipeline() .collection("books") .distinct([ Field("author").toUpper().as("author"), Field("genre") ]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .distinct( field("author").toUpper().alias("author"), field("genre") ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .distinct( field("author").toUpper().alias("author"), field("genre") ) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .distinct(Field.of("author").to_upper().as_("author"), "genre") .execute() )
Hàm
Hàm là một thành phần để tạo biểu thức và truy vấn phức tạp. Để biết danh sách đầy đủ các hàm có ví dụ, hãy tham khảo Tài liệu tham khảo về hàm. Để nhắc lại nhanh, hãy xem xét cấu trúc của một truy vấn điển hình:

Nhiều giai đoạn chấp nhận các biểu thức chứa một hoặc nhiều hàm. Bạn sẽ tìm thấy cách sử dụng hàm phổ biến nhất trong các giai đoạn where(...) và select(...). Có 2 loại hàm chính mà bạn nên làm quen:
Web
let results; // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = await execute(db.pipeline().collection("books") .select(field("current").logicalMinimum(field("updated")).as("price_min")) ); // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = await execute(db.pipeline().collection("books") .aggregate(field("price").minimum().as("min_price")) );
Swift
var results: Pipeline.Snapshot // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = try await db.pipeline().collection("books") .select([ Field("current").logicalMinimum(["updated"]).as("price_min") ]) .execute() // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = try await db.pipeline().collection("books") .aggregate([Field("price").minimum().as("min_price")]) .execute()
Kotlin
var results: Task<Pipeline.Snapshot> // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = db.pipeline().collection("books") .select( field("current").logicalMinimum("updated").alias("price_min") ) .execute() // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = db.pipeline().collection("books") .aggregate(AggregateFunction.minimum("price").alias("min_price")) .execute()
Java
Task<Pipeline.Snapshot> results; // Type 1: Scalar (for use in non-aggregation stages) // Example: Return the min store price for each book. results = db.pipeline().collection("books") .select( field("current").logicalMinimum("updated").alias("price_min") ) .execute(); // Type 2: Aggregation (for use in aggregate stages) // Example: Return the min price of all books. results = db.pipeline().collection("books") .aggregate(AggregateFunction.minimum("price").alias("min_price")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field # Type 1: Scalar (for use in non-aggregation stages) # Example: Return the min store price for each book. results = ( client.pipeline() .collection("books") .select( Field.of("current").logical_minimum(Field.of("updated")).as_("price_min") ) .execute() ) # Type 2: Aggregation (for use in aggregate stages) # Example: Return the min price of all books. results = ( client.pipeline() .collection("books") .aggregate(Field.of("price").minimum().as_("min_price")) .execute() )
Giới hạn
Phần lớn, phiên bản Enterprise không áp đặt giới hạn về hình dạng của truy vấn. Nói cách khác, bạn không bị giới hạn ở một số lượng nhỏ giá trị trong truy vấn IN hoặc OR. Thay vào đó, có 2 giới hạn chính mà bạn cần lưu ý:
- Thời hạn: 60 giây (giống như phiên bản Standard).
- Mức sử dụng bộ nhớ: Giới hạn 128 MiB về lượng dữ liệu được hiện thực hoá trong quá trình thực thi truy vấn.
Lỗi
Bạn có thể gặp phải các truy vấn không thành công vì một số lý do. Dưới đây là đường liên kết đến các lỗi thường gặp và hành động liên quan mà bạn có thể thực hiện:
| Mã lỗi | Hành động |
DEADLINE_EXCEEDED
|
Truy vấn mà bạn đang thực thi vượt quá thời hạn 60 giây và cần được tối ưu hoá thêm. Hãy xem phần hiệu suất để biết các mẹo. Nếu bạn không thể xác định nguyên nhân gốc rễ của vấn đề, hãy liên hệ với nhóm. |
RESOURCE_EXHAUSTED
|
Truy vấn mà bạn đang thực thi vượt quá giới hạn bộ nhớ và cần được tối ưu hoá thêm. Hãy xem phần hiệu suất để biết các mẹo. Nếu bạn không thể xác định nguyên nhân gốc rễ của vấn đề, hãy liên hệ với nhóm. |
INTERNAL
|
Liên hệ với nhóm để được hỗ trợ. |
Hiệu suất
Không giống như các truy vấn hiện có, các hoạt động của quy trình không yêu cầu phải luôn có chỉ mục. Điều này có nghĩa là một truy vấn có thể có độ trễ cao hơn so với các truy vấn hiện có, vốn sẽ thất bại ngay lập tức với lỗi chỉ mục FAILED_PRECONDITION bị thiếu. Để cải thiện hiệu quả của các hoạt động của pipeline, bạn có thể thực hiện một số bước.
Tạo chỉ mục
Chỉ mục đã sử dụng
Tính năng giải thích truy vấn cho phép bạn xác định xem truy vấn của mình đang được một chỉ mục phân phát hay đang quay lại một thao tác kém hiệu quả hơn như quét bảng. Nếu truy vấn của bạn không được phân phát đầy đủ từ một chỉ mục, bạn có thể tạo một chỉ mục bằng cách làm theo hướng dẫn.
Tạo chỉ mục
Bạn có thể làm theo tài liệu hiện có về quản lý chỉ mục để tạo chỉ mục. Trước khi tạo chỉ mục, hãy làm quen với các phương pháp hay nhất chung về chỉ mục trong Cloud Firestore. Để đảm bảo truy vấn của bạn có thể tận dụng chỉ mục, hãy làm theo các phương pháp hay nhất để tạo chỉ mục có các trường theo thứ tự sau:
- Tất cả các trường sẽ được sử dụng trong bộ lọc đẳng thức (theo bất kỳ thứ tự nào)
- Tất cả các trường sẽ được sắp xếp (theo cùng một thứ tự)
- Các trường sẽ được sử dụng trong bộ lọc phạm vi hoặc bộ lọc bất đẳng thức theo thứ tự giảm dần của mức độ chọn lọc ràng buộc truy vấn
Ví dụ: đối với truy vấn sau,
Web
const results = await execute(db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) );
Swift
let results = try await db.pipeline() .collection("books") .where(Field("published").lessThan(1900)) .where(Field("genre").equal("Science Fiction")) .where(Field("rating").greaterThan(4.3)) .sort([Field("published").descending()]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .where(field("published").lessThan(1900)) .where(field("genre").equal("Science Fiction")) .where(field("rating").greaterThan(4.3)) .sort(field("published").descending()) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .where(Field.of("published").less_than(1900)) .where(Field.of("genre").equal("Science Fiction")) .where(Field.of("rating").greater_than(4.3)) .sort(Field.of("published").descending()) .execute() )
Chỉ mục được đề xuất là chỉ mục phạm vi tập hợp trên books cho (genre [...], published DESC, avg_rating DESC).
Mật độ chỉ mục
Cloud Firestore hỗ trợ chỉ mục thưa và không thưa. Để biết thêm thông tin, xem Mật độ chỉ mục.
Truy vấn được bao phủ + Chỉ mục thứ cấp
Cloud Firestore có thể bỏ qua việc tìm nạp toàn bộ tài liệu và chỉ trả về kết quả từ chỉ mục nếu tất cả các trường được trả về đều có trong chỉ mục thứ cấp. Điều này thường dẫn đến việc cải thiện đáng kể độ trễ (và chi phí). Sử dụng truy vấn mẫu bên dưới:
Web
const results = await execute(db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) );
Swift
let results = try await db.pipeline() .collection("books") .where(Field("category").like("%fantasy%")) .where(Field("title").exists()) .where(Field("author").exists()) .select([Field("title"), Field("author")]) .execute()
Kotlin
val results = db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("books") .where(field("category").like("%fantasy%")) .where(field("title").exists()) .where(field("author").exists()) .select(field("title"), field("author")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field results = ( client.pipeline() .collection("books") .where(Field.of("category").like("%fantasy%")) .where(Field.of("title").exists()) .where(Field.of("author").exists()) .select("title", "author") .execute() )
Nếu cơ sở dữ liệu đã có chỉ mục phạm vi tập hợp trên books cho (category [...], title [...], author [...]), thì cơ sở dữ liệu đó có thể tránh tìm nạp bất kỳ nội dung nào từ chính các tài liệu chính. Trong trường hợp này, thứ tự trong chỉ mục không quan trọng, [...] được dùng để biểu thị điều đó.
Giới hạn các trường cần trả về
Theo mặc định, một Cloud Firestore truy vấn trả về tất cả các trường trong một tài liệu, tương tự như một SELECT * trong các hệ thống truyền thống. Tuy nhiên, nếu ứng dụng của bạn chỉ cần một tập hợp con các trường, thì bạn có thể sử dụng các giai đoạn select(...) hoặc restrict(...) để đẩy quá trình lọc này ở phía máy chủ. Điều này sẽ làm giảm cả kích thước phản hồi (giảm chi phí truyền dữ liệu ra khỏi mạng) cũng như cải thiện độ trễ.
Công cụ khắc phục sự cố
Giải thích truy vấn
Tính năng giải thích truy vấn cho phép bạn xem các chỉ số thực thi và thông tin chi tiết về các chỉ mục được sử dụng.
Chỉ số
Các hoạt động của quy trình nếu được tích hợp đầy đủ với các chỉ số Cloud Firestore hiện có.
Các vấn đề / hạn chế đã biết
Chỉ mục chuyên biệt
Các hoạt động của quy trình chưa hỗ trợ các loại chỉ mục array-contains & vector hiện có. Thay vì chỉ từ chối các truy vấn như vậy, Cloud Firestore sẽ cố gắng sử dụng các chỉ mục ascending & descending hiện có khác. Dự kiến trong quá trình xem trước riêng tư, các hoạt động của quy trình có các biểu thức array_contains hoặc find_nearest như vậy sẽ chậm hơn so với các biểu thức tương đương hiện có do điều này.
Đánh số trang
Chúng tôi không hỗ trợ tính năng dễ dàng phân trang trên một tập hợp kết quả trong quá trình xem trước riêng tư. Bạn có thể giải quyết vấn đề này bằng cách xâu chuỗi các giai đoạn where(...) và sort(...) tương đương như minh hoạ bên dưới.
Web
// Existing pagination via `startAt()` const q = query(collection(db, "cities"), orderBy("population"), startAt(1000000)); // Private preview workaround using pipelines const pageSize = 2; const pipeline = db.pipeline() .collection("cities") .select("name", "population", "__name__") .sort(field("population").descending(), field("__name__").ascending()); // Page 1 results let snapshot = await execute(pipeline.limit(pageSize)); // End of page marker const lastDoc = snapshot.results[snapshot.results.length - 1]; // Page 2 results snapshot = await execute( pipeline .where( or( and( field("population").equal(lastDoc.get("population")), field("__name__").greaterThan(lastDoc.ref) ), field("population").lessThan(lastDoc.get("population")) ) ) .limit(pageSize) );
Swift
// Existing pagination via `start(at:)` let query = db.collection("cities").order(by: "population").start(at: [1000000]) // Private preview workaround using pipelines let pipeline = db.pipeline() .collection("cities") .where(Field("population").greaterThanOrEqual(1000000)) .sort([Field("population").descending()])
Kotlin
// Existing pagination via `startAt()` val query = db.collection("cities").orderBy("population").startAt(1000000) // Private preview workaround using pipelines val pipeline = db.pipeline() .collection("cities") .where(field("population").greaterThanOrEqual(1000000)) .sort(field("population").descending())
Java
// Existing pagination via `startAt()` Query query = db.collection("cities").orderBy("population").startAt(1000000); // Private preview workaround using pipelines Pipeline pipeline = db.pipeline() .collection("cities") .where(field("population").greaterThanOrEqual(1000000)) .sort(field("population").descending());
Python
from google.cloud.firestore_v1.pipeline_expressions import Field # Existing pagination via `start_at()` query = ( client.collection("cities") .order_by("population") .start_at({"population": 1_000_000}) ) # Private preview workaround using pipelines pipeline = ( client.pipeline() .collection("cities") .where(Field.of("population").greater_than_or_equal(1_000_000)) .sort(Field.of("population").descending()) )
Hỗ trợ trình mô phỏng
Trình mô phỏng không hỗ trợ các hoạt động của quy trình.
Hỗ trợ theo thời gian thực và ngoại tuyến
Các hoạt động của quy trình chưa có các tính năng theo thời gian thực và ngoại tuyến.
Bước tiếp theo
- Bắt đầu khám phá tài liệu tham khảo về Hàm và Giai đoạn.