MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Memetakan dokumen MongoDB ke kelas kasus dengan tipe tetapi tanpa dokumen yang disematkan

Iya itu mungkin. Sebenarnya ini lebih sederhana daripada memiliki sub-dokumen "pengguna" dalam "tweet". Ketika "pengguna" adalah referensi, itu hanya nilai skalar, MongoDB dan "Subset" tidak memiliki mekanisme untuk mengkueri bidang subdokumen.

Saya telah menyiapkan cuplikan kode REPLable sederhana untuk Anda (diasumsikan Anda memiliki dua koleksi -- "tweets" dan "users").

Persiapan...

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 kami kelas kasus

case class User(_id: ObjectId, name: String)

Sejumlah bidang untuk tweet dan pengguna

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

Di sini hal-hal yang lebih rumit mulai terjadi. Yang kita butuhkan adalah ValueReader yang mampu mendapatkan ObjectId berdasarkan nama bidang, tetapi kemudian pergi ke koleksi lain dan membaca objek dari sana.

Ini dapat ditulis sebagai satu bagian kode, yang melakukan semua hal sekaligus (Anda mungkin melihat varian seperti itu dalam riwayat jawaban), tetapi akan lebih idiomatis untuk mengekspresikannya sebagai kombinasi pembaca. Misalkan kita memiliki ValueReader[User] yang membaca dari DBObject :

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

Yang tersisa adalah ValueReader[T] generik yang mengharapkan ObjectId dan mengambil objek dari koleksi tertentu menggunakan pembaca dasar yang disediakan:

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
    }
}

Kemudian, kita dapat mengatakan kelas tipe kita untuk membaca User s dari referensi hanyalah

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

Dan inilah cara Anda menggunakannya:

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. Migrasi Data dari Oracle ke Mongo DB

  2. Perbarui dengan AddToSet tidak memperbarui nilai nol dengan MongoDB C#

  3. Apakah MongoDB mendukung tipe floating point?

  4. Menggunakan fungsionalitas Mongoose / MongoDB $addToSet pada array objek

  5. Pendefinisian skema Mongodb