All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.mongocamp.driver.mongodb.MongoDAO.scala Maven / Gradle / Ivy

There is a newer version: 2.8.1
Show newest version
package dev.mongocamp.driver.mongodb

import better.files.File
import dev.mongocamp.driver.mongodb.bson.{ BsonConverter, DocumentHelper }
import dev.mongocamp.driver.mongodb.database.{ ChangeObserver, CollectionStatus, CompactResult, DatabaseProvider }
import dev.mongocamp.driver.mongodb.operation.Crud
import org.bson.json.JsonParseException
import org.mongodb.scala.model.Accumulators._
import org.mongodb.scala.model.Aggregates._
import org.mongodb.scala.model.Filters._
import org.mongodb.scala.model.Projections
import org.mongodb.scala.{ BulkWriteResult, Document, MongoCollection, Observable, SingleObservable }

import java.nio.charset.Charset
import java.util.Date
import scala.collection.mutable.ArrayBuffer
import scala.reflect.ClassTag

/** Created by tom on 20.01.17.
  */
abstract class MongoDAO[A](provider: DatabaseProvider, collectionName: String)(implicit ct: ClassTag[A]) extends Crud[A] {

  val databaseName: String = provider.guessDatabaseName(collectionName)

  val name: String = provider.guessName(collectionName)

  val collection: MongoCollection[A] = provider.collection[A](collectionName)

  def addChangeObserver(observer: ChangeObserver[A]): ChangeObserver[A] = {
    coll.watch[A]().subscribe(observer)
    observer
  }

  def collectionStatus: Observable[CollectionStatus] = {
    provider.runCommand(Map("collStats" -> collectionName)).map(document => CollectionStatus(document))
  }

  def compact: Observable[Option[CompactResult]] = {
    val startDate = new Date()
    provider
      .runCommand(Map("compact" -> collectionName))
      .map(document => CompactResult(s"$databaseName${DatabaseProvider.CollectionSeparator}$collectionName", document, startDate))
  }

  /** @param sampleSize
    *   use sample size greater 0 for better performance on big collections
    * @return
    *   List of column names
    */
  def columnNames(sampleSize: Int = 0, maxWait: Int = DefaultMaxWait): List[String] = {
    val projectStage = project(Projections.computed("tempArray", equal("$objectToArray", "$$ROOT")))
    val unwindStage  = unwind("$tempArray")
    val groupStage   = group("_id", addToSet("keySet", "$tempArray.k"))
    val pipeline = {
      if (sampleSize > 0) {
        List(sample(sampleSize), projectStage, unwindStage, groupStage)
      }
      else {
        List(projectStage, unwindStage, groupStage)
      }
    }

    val aggregationResult: Document = Raw.findAggregated(pipeline).result(maxWait)
    BsonConverter.fromBson(aggregationResult.get("keySet").head).asInstanceOf[List[String]]
  }

  protected def coll: MongoCollection[A] = collection

  // internal object for raw document access
  object Raw extends MongoDAO[Document](provider, collectionName)

  def importJsonFile(file: File): SingleObservable[BulkWriteResult] = {
    val docs = new ArrayBuffer[Document]()
    try {
      if (file.exists) {
        val iterator = file.lineIterator(Charset.forName("UTF-8"))
        iterator.foreach(line => docs.+=(DocumentHelper.documentFromJsonString(line).get))
      }
    }
    catch {
      case e: JsonParseException =>
        logger.error(e.getMessage, e)
    }
    Raw.bulkWriteMany(docs.toSeq)
  }

  override def toString: String = "%s:%s@%s, %s".format(databaseName, collectionName, provider.config, super.toString)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy