MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Ánh xạ tài liệu MongoDB sang lớp chữ hoa chữ thường với các loại nhưng không có tài liệu nhúng

Vâng nó có thể. Trên thực tế, nó thậm chí còn đơn giản hơn việc có một tài liệu phụ "người dùng" trong một "tweet". Khi "người dùng" là một tham chiếu, nó chỉ là một giá trị vô hướng, MongoDB và "Tập hợp con" không có cơ chế để truy vấn các trường tài liệu con.

Tôi đã chuẩn bị một đoạn mã REPLable đơn giản cho bạn (giả sử bạn có hai bộ sưu tập - "tweet" và "người dùng").

Chuẩn bị ...

import org.bson.types.ObjectId
import com.mongodb._
import com.osinka.subset._
import Document.DocumentId

val db = new Mongo("localhost") getDB "test"
val tweets = db getCollection "tweets"
val users = db getCollection "users"

User của chúng tôi trường hợp lớp

Người dùng
case class User(_id: ObjectId, name: String)

Một số trường dành cho tweet và người dùng

val content = "content".fieldOf[String]
val user = "user".fieldOf[User]
val name = "name".fieldOf[String]

Ở đây những điều phức tạp hơn bắt đầu xảy ra. Những gì chúng ta cần là một ValueReader có khả năng nhận được ObjectId dựa trên tên trường, nhưng sau đó chuyển đến một bộ sưu tập khác và đọc một đối tượng từ đó.

Điều này có thể được viết dưới dạng một đoạn mã duy nhất, thực hiện tất cả mọi thứ cùng một lúc (bạn có thể thấy một biến thể như vậy trong lịch sử câu trả lời), nhưng sẽ khó hiểu hơn nếu diễn đạt nó như một sự kết hợp của các trình đọc. Giả sử chúng ta có ValueReader[User] đọc từ DBObject :

val userFromDBObject = ValueReader({
  case DocumentId(id) ~ name(name) => User(id, name)
})

Những gì còn lại là một ValueReader[T] chung chung điều đó mong đợi ObjectId và truy xuất một đối tượng từ một bộ sưu tập cụ thể bằng cách sử dụng trình đọc bên dưới được cung cấp:

class RefReader[T](val collection: DBCollection, val underlying: ValueReader[T]) extends ValueReader[T] {
  override def unpack(o: Any):Option[T] =
    o match {
      case id: ObjectId =>
        Option(collection findOne id) flatMap {underlying.unpack _}
      case _ =>
        None
    }
}

Sau đó, chúng ta có thể nói lớp loại của chúng ta để đọc User s từ các tài liệu tham khảo chỉ là

implicit val userReader = new RefReader[User](users, userFromDBObject)

Và đây là cách bạn sẽ sử dụng nó:

import collection.JavaConverters._

tweets.find.iterator.asScala foreach { 
  case Document.DocumentId(id) ~ content(content) ~ user(u) =>
    println("%s - %s by %s".format(id, content, u))
}


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Làm thế nào để tính toán phần trăm sử dụng khía cạnh trong MongoDB?

  2. Sự cố trùng lặp Mongo DB khi sử dụng sắp xếp có giới hạn và bỏ qua trong tổng hợp

  3. Cách xóa các phiên cũ / cũ khi sử dụng lưu trữ phiên Mongo DB trong Ruby on Rails 3.2

  4. MongoDB - Tạo cơ sở dữ liệu

  5. tôi có thể chuyển truy vấn mongodb dưới dạng một chuỗi trong php không