Câu trả lời này đã được viết lại.
Hầu hết người lập bản đồ dữ liệu hoạt động bằng cách biểu diễn một đối tượng trên mỗi lớp hoặc "mô hình" thường là thuật ngữ được đặt ra. Nếu bạn muốn cho phép nhiều lần truy cập thông qua một đối tượng duy nhất (ví dụ: $model->find()
), nó thường bị demmed sao cho phương thức sẽ không thực sự trả về một thể hiện của chính nó mà thay vào đó là một mảng hoặc MongoCursor
các lớp tải mong muốn vào không gian.
Mô hình như vậy thường được kết nối với "Active Record". Đây là phương pháp mà ORM, ODM và khung công tác sử dụng để giao tiếp với cơ sở dữ liệu theo cách này hay cách khác, không chỉ cho MongoDB mà còn cho SQL và bất kỳ cơ sở dữ liệu nào khác xảy ra để trồng lên (Cassandra, CouchDB v.v.).
Cần lưu ý rằng ngay cả khi bản ghi hoạt động cung cấp nhiều quyền lực, nó không được bỏ qua toàn bộ ứng dụng. Có những lúc sử dụng trình điều khiển trực tiếp sẽ mang lại nhiều lợi ích hơn. Hầu hết các ORM, ODM và khung công tác đều cung cấp khả năng truy cập trực tiếp vào trình điều khiển một cách nhanh chóng và dễ dàng vì lý do này.
Có nhiều người cho rằng, không có người lập bản đồ dữ liệu trọng lượng nhẹ. Nếu bạn định ánh xạ dữ liệu được trả về của bạn vào các lớp thì nó sẽ tiêu thụ tài nguyên, kết thúc. Lợi ích của việc này là sức mạnh bạn nhận được khi thao tác các đối tượng của bạn.
Bản ghi hoạt động thực sự tốt khi có thể cung cấp các sự kiện và trình kích hoạt từ bên trong PHP.Một ví dụ điển hình là của một ORM tôi thực hiện cho Yii: https://github.com/Sammaye/MongoYii nó có thể cung cấp móc cho:
afterConstruct
beforeFind
afterFind
beforeValidate
afterValidate
beforeSave
afterSave
Cần lưu ý rằng khi nói đến những sự kiện như beforeSave
và afterSave
MongoDB không có trigger (https://jira.mongodb.org/browse/SERVER-124) để nó có ý nghĩa rằng việc áp dụng nên xử lý này. Trên lý do rõ ràng cho ứng dụng xử lý điều này, nó cũng giúp xử lý tốt hơn các hàm tiết kiệm bằng cách có thể gọi các hàm PHP gốc của bạn để thao tác mọi tài liệu được lưu trước khi chạm vào cơ sở dữ liệu.
Hầu hết người lập bản đồ dữ liệu hoạt động bằng cách sử dụng CRUD lớp riêng của PHP để đại diện cho họ. Ví dụ để tạo ra một kỷ lục mới:
$d=new User();
$d->username='sammaye';
$d->save();
Đây là một cách tiếp cận khá tốt kể từ khi bạn tạo ra một "mới" (https://github.com/Sammaye/MongoYii/blob/master/EMongoDocument.php#L46 cho thấy làm thế nào tôi chuẩn bị cho một kỷ lục mới trong MongoYii) lớp để tạo ra một kỷ lục "mới". Nó khá phù hợp với ngữ nghĩa.
Chức năng cập nhật thường được truy cập thông qua chức năng đọc, bạn không thể cập nhật mô hình mà bạn không biết tồn tại. Điều này đưa chúng ta đến bước tiếp theo của các mô hình dân cư.
Để xử lý việc tạo mô hình ORM khác nhau, ODM và khung công tác cam kết với các phương pháp khác nhau. Ví dụ, phần mở rộng MongoYii của tôi sử dụng một phương thức nhà máy được gọi là model
trong mỗi lớp để mang lại một thể hiện mới của chính nó để tôi có thể gọi số động find
và findOne
và các phương pháp khác.
Một số ORM, ODM và khung cung cấp chức năng đọc như các hàm trực tiếp static
làm cho chúng trở thành phương thức nhà máy trong khi một số sử dụng mẫu đơn, tuy nhiên, tôi đã chọn không (https://stackoverflow.com/a/4596323/383478).
Hầu hết, nếu không phải tất cả, hãy triển khai một số dạng con trỏ. Điều này được sử dụng để trả về bội số của các mô hình và kết thúc trực tiếp (thông thường) MongoCursor
để thay thế phương thức current()
bằng cách trả về một mô hình được điền trước.
Ví dụ gọi:
User::model()->find();
Would return một EMongoCursor
(trong MongoYii) mà sau đó sẽ sotre thực tế là lớp User
đã được sử dụng để nhanh chóng các con trỏ và khi được gọi như:
foreach(User::model() as $k=>$v){
var_dump($v);
}
Gọi phương thức current()
tại đây: https://github.com/Sammaye/MongoYii/blob/master/EMongoCursor.php#L102 trả về một phiên bản mới của mô hình.
Có một số ORM, ODM và khung thực hiện tải mảng mong muốn.Điều này có nghĩa là họ sẽ tải toàn bộ kết quả thẳng vào RAM của bạn dưới dạng một loạt các mô hình. Cá nhân tôi không thích cách tiếp cận này, nó lãng phí và cũng không tốt khi bạn cần sử dụng bản ghi hoạt động cho bản cập nhật lớn hơn do thêm một số chức năng mới ở những nơi cần thêm vào bản ghi cũ.
Một chủ đề cuối cùng trước khi tôi tiếp tục là bản chất schemaless của MongoDB. Vấn đề với việc sử dụng các lớp PHP với MongoDB là bạn muốn tất cả các chức năng của PHP nhưng với tính chất biến của MongoDB. Điều này dễ dàng hơn trong SQL vì nó có một lược đồ được xác định trước, bạn chỉ cần truy vấn nó và các công việc đã làm; tuy nhiên, MongoDB không có thứ gì như vậy.
Điều này làm cho việc xử lý lược đồ trong MongoDB khá nguy hiểm. Hầu hết các ORM, ODM và khuôn khổ yêu cầu bạn xác định trước lược đồ tại chỗ (tức là Doctrine 2) sử dụng các biến số private
với các phương thức get
và set
. Trong MongoYii, để làm cho cuộc sống của tôi dễ dàng và thanh lịch, tôi quyết định giữ lại bản chất của MongoDBs bằng cách sử dụng các phép thuật có thể phát hiện (https://github.com/Sammaye/MongoYii/blob/master/EMongoModel.php#L26 là __get
và https://github.com/Sammaye/MongoYii/blob/master/EMongoModel.php#L47 là __set
), nếu thuộc tính wa không thể truy cập được trong lớp, mảng nội bộ _attributes
và nếu không thì chỉ cần trả lại null
. Tương tự như vậy, để thiết lập một thuộc tính tôi sẽ chỉ đặt trong biến số _attributes
bên trong.
Đối với giao dịch với cách chỉ định lược đồ này, tôi đã chuyển nhượng nội bộ cho người dùng, để xử lý các thuộc tính thiết lập từ biểu mẫu v.v. Tôi đã sử dụng quy tắc xác thực (https://github.com/Sammaye/MongoYii/blob/master/EMongoModel.php#L236) gọi hàm getSafeAttributeNames()
. có quy tắc xác thực chống lại chúng. Nếu họ không có quy tắc xác thực thì các thuộc tính đó đã tồn tại trong mảng $_POST
hoặc $_GET
sắp tới sẽ không được đặt. Vì vậy, điều này cung cấp khả năng cho một lược đồ, nhưng an toàn, cấu trúc mô hình.
Vì vậy, chúng tôi đã đề cập đến cách thực sự sử dụng tài liệu gốc, bạn cũng hỏi cách người lập bản đồ dữ liệu xử lý các tài liệu phụ. Doctrine 2 và nhiều thứ khác cung cấp các subdocuments dựa trên lớp đầy đủ (http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/embedded-mapping.html) nhưng điều này có thể cực kỳ tháo vát. Thay vào đó, tôi quyết định rằng tôi sẽ cung cấp các chức năng trợ giúp cho phép sử dụng linh hoạt subdocument mà không mong muốn tải chúng vào các mô hình và do đó tiêu thụ RAM. Về cơ bản những gì tôi đã làm là để lại cho họ khi họ là một cung cấp một validator (https://github.com/Sammaye/MongoYii/blob/master/validators/ESubdocumentValidator.php) để xác nhận bên trong của họ. Tất nhiên trình duyệt tính hợp lệ sẽ tự sinh ra nếu bạn có một quy tắc trong trình xác nhận hợp lệ đã sử dụng trình xác nhận hợp lệ một lần nữa để đưa ra một xác nhận hợp lệ của một tài liệu con lồng nhau thì nó sẽ hoạt động.
Vì vậy, tôi nghĩ hoàn thành một cuộc thảo luận rất cơ bản về ORM, ODM và khung sử dụng người lập bản đồ dữ liệu. Tất nhiên tôi có lẽ có thể viết toàn bộ một bài luận về điều này nhưng đây là một cuộc thảo luận đủ tốt cho phút tôi tin.
Nếu bạn giải thích thêm về loại câu trả lời bạn muốn chúng tôi có thể cung cấp một câu trả lời, tôi muốn viết mã cho bạn những gì bạn muốn? – Sammaye
Bạn đang trình bày một cách tiếp cận mang tính xây dựng và hữu ích đối với tôi, và tôi đã học được nhiều về kỹ thuật và việc thực hiện của bạn. Cảm ơn vì điều đó! Ngoài ra, tôi mở ra bất kỳ cách tiếp cận nào khác ngoài đó, tôi sẵn sàng xem nó, nếu nó tồn tại. Tôi đang cố gắng khám phá tất cả các khả năng và các mẫu về vấn đề này. – Dyin