2017-10-22 23 views
14

Nói rằng tôi có loại cấu trúcFireStore nhận được tất cả tài liệu và bộ sưu tập con của bộ sưu tập gốc

A (collection): { 
     a (doc): { 
      name:'Tim', 
      B (collection):{ 
       b (doc): { 
         color:'blue' 
       } 
      } 
      } 
    } 

nơi ABbộ sưu tập khi abtài liệu.
Có cách nào để tải mọi thứ trong tài liệu gốc bằng một truy vấn không?
Nếu tôi truy vấn như thế này

db.collection("A").doc("a").get() 

Tôi chỉ được name:'Tim' lĩnh vực. Những gì tôi muốn là để có được tất cả các tài liệu của B.
tôi về cơ bản muốn truy vấn của tôi trả

  { 
      user:'Tim', 
      B (collection):{ 
       b (doc): { 
         color:'blue' 
       } 
      } 
      } 

là nó có thể hoặc làm tôi thực sự cần phải thực hiện nhiều truy vấn một cho mỗi bộ sưu tập: /?

Giả sử tôi có một bộ sưu tập lồng nhau thực sự đại diện cho hồ sơ người dùng, chi phí của tôi sẽ tăng lên như địa ngục kể từ khi tôi tải hồ sơ người dùng tôi có số yêu cầu đọc 1 x N trong đó N là độ sâu của cây của tôi : /.

+0

gì loại là 'B'? Có một loại tham chiếu bạn có thể thử. – JonZarate

+0

Loại tham chiếu kết thúc với cùng một vấn đề, dữ liệu không được tìm nạp. –

Trả lời

8

Như chúng ta biết, truy vấn trong Cloud Firestore bị cạn theo mặc định. Loại truy vấn này không được hỗ trợ, mặc dù đây là điều mà Google có thể xem xét trong tương lai.

11

Nếu bạn lo lắng về chi phí của mỗi lần kéo, bạn sẽ cần phải cấu trúc dữ liệu theo nhu cầu xem/kéo thông thường của bạn, thay vì những gì bạn có thể thích cho một cấu trúc hoàn hảo. Nếu bạn cần phải kéo những thứ này lại với nhau mọi lúc, Consider using "maps" cho những thứ không thực sự cần phải là bộ sưu tập phụ với tài liệu.

Trong ví dụ này, "tùy chọn" là bản đồ.

{ 
    user: "Tim", 
    preferences: { 
     color: "blue", 
     nickname: "Timster" 
    } 
} 

Mỗi tài liệu cũng được giới hạn về kích thước 1MB - vì vậy nếu bạn cần lưu trữ một cái gì đó cho người dùng này sẽ mở rộng quy mô và tiếp tục phát triển, giống như hồ sơ đăng nhập, sau đó nó sẽ làm cho tinh thần để phá vỡ bản ghi vào một tiểu -Bộ sưu tập chỉ được kéo khi bạn muốn, và mỗi mục nhập nhật ký là một tài liệu riêng biệt ... Và liệu tất cả nhật ký cho tất cả người dùng được lưu trữ trong bộ sưu tập cha mẹ riêng biệt hay một tập hợp con của mỗi người dùng thực sự phụ thuộc vào cách bạn sẽ được kéo các bản ghi và những gì sẽ cho kết quả tốc độ nhanh, cân đối với chi phí của kéo. Nếu bạn đang hiển thị cho người dùng này 10 tìm kiếm cuối cùng của họ thì nhật ký tìm kiếm sẽ có ý nghĩa tốt như một tập hợp con. Nếu bạn đang kéo tất cả dữ liệu tìm kiếm cho tất cả người dùng để phân tích, thì một bộ sưu tập cấp độ gốc riêng biệt sẽ có ý nghĩa bởi vì bạn có thể kéo tất cả các nhật ký trong 1 lần kéo để ngăn nhu cầu tách nhật ký từ từng người dùng một cách riêng biệt.

Bạn cũng có thể lồng kéo và hứa hẹn cùng nhau vì mục đích thuận tiện.

// Get reference to all of the documents 
    console.log("Retrieving list of documents in collection"); 
    let documents = collectionRef.limit(1).get() 
    .then(snapshot => { 
     snapshot.forEach(doc => { 
     console.log("Parent Document ID: ", doc.id); 

     let subCollectionDocs = collectionRef.doc(doc.id).collection("subCollection").get() 
      .then(snapshot => { 
      snapshot.forEach(doc => { 
       console.log("Sub Document ID: ", doc.id); 
      }) 
      }).catch(err => { 
      console.log("Error getting sub-collection documents", err); 
      }) 
     }); 
    }).catch(err => { 
    console.log("Error getting documents", err); 
    }); 
+0

Đối với tôi, bên ngoài forEach hoàn thành trước khi nó xử lý bất kỳ mục bên trong nào, vì vậy các mục bên trong không được liên kết với đúng tài liệu gốc. Đầu ra: https://www.dropbox.com/s/2u831pue7edym2w/Screenshot%202017-12-21%2020.33.28.png?dl=0 – AdamG

+0

Điều này phụ thuộc vào những gì bạn cần làm với dữ liệu. Mục tiêu ở đây là lấy tất cả dữ liệu. Nếu bạn cần nó để in ra hoặc được xử lý đồng bộ, bạn có thể cần phải sử dụng một chức năng truy cập/đệ quy với một cuộc gọi lại để làm một tại một thời điểm. Hãy nhớ rằng sẽ làm tăng đáng kể chi phí đọc/ghi của bạn. Nếu bạn chỉ cần tất cả các dữ liệu, sau đó bạn có tất cả và có thể làm như bạn vui lòng với nó. –

0

Thêm vào Matt R câu trả lời, nếu bạn đang sử dụng babel hoặc bạn có thể sử dụng async/chờ đợi, bạn có thể nhận được kết quả tương tự với mã ít hơn (không catch/then):

// Get reference to all of the documents 
console.log("Retrieving list of documents in collection"); 
let documents = await collectionRef.get(); 

documents.forEach(async doc => { 
    console.log("Parent Document ID: ", doc.id); 
    let subCollectionDocs = await collectionRef.doc(doc.id).collection("subCollection").get() 
    subCollectionDocs.forEach(subCollectionDoc => { 
    subCollectionDoc.forEach(doc => { 
     console.log("Sub Document ID: ", doc.id); 
    }) 
}); 
Các vấn đề liên quan