Skip to content

Commit ed3e253

Browse files
committed
add columnNames function (by aggregation) in MongoDAO
1 parent e0f65f4 commit ed3e253

File tree

4 files changed

+42
-7
lines changed

4 files changed

+42
-7
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
## Versions
55

6+
### 2.0.8
7+
* MongoDAO add method columnNames
8+
69
### 2.0.7
710
* mongo-scala-driver [4.1.0](https://mongodb.github.io/mongo-java-driver/4.1/whats-new/)
811

src/main/scala/com/sfxcode/nosql/mongo/MongoDAO.scala

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@ package com.sfxcode.nosql.mongo
33
import java.nio.charset.Charset
44

55
import better.files.File
6-
import com.sfxcode.nosql.mongo.bson.DocumentHelper
6+
import com.sfxcode.nosql.mongo.bson.{BsonConverter, DocumentHelper}
77
import com.sfxcode.nosql.mongo.database.{ChangeObserver, CollectionStatus, DatabaseProvider}
88
import com.sfxcode.nosql.mongo.operation.Crud
99
import org.bson.json.JsonParseException
10+
import org.mongodb.scala.model.Aggregates.project
11+
import org.mongodb.scala.model.Projections
1012
import org.mongodb.scala.{BulkWriteResult, Document, MongoCollection, Observable, SingleObservable}
1113

1214
import scala.collection.mutable.ArrayBuffer
1315
import scala.reflect.ClassTag
16+
import org.mongodb.scala.model.Filters._
17+
import org.mongodb.scala.model.Aggregates._
18+
import org.mongodb.scala.model.Accumulators._
1419

1520
/**
1621
* Created by tom on 20.01.17.
@@ -32,18 +37,36 @@ abstract class MongoDAO[A](provider: DatabaseProvider, collectionName: String)(i
3237
def collectionStatus: Observable[CollectionStatus] =
3338
provider.runCommand(Map("collStats" -> collectionName)).map(document => CollectionStatus(document))
3439

40+
/**
41+
*
42+
* @param sampleSize use sample size greate 0 for better performance on big collections
43+
* @return List of column names
44+
*/
45+
def columnNames(sampleSize: Int = 0): List[String] = {
46+
val projectStage = project(Projections.computed("tempArray", equal("$objectToArray", "$$ROOT")))
47+
val unwindStage = unwind("$tempArray")
48+
val groupStage = group("_id", addToSet("keySet", "$tempArray.k"))
49+
val pipeline = {
50+
if (sampleSize > 0)
51+
List(projectStage, unwindStage, groupStage, sample(sampleSize))
52+
else
53+
List(projectStage, unwindStage, groupStage)
54+
}
55+
56+
val aggregationResult: Document = Raw.findAggregated(pipeline).result()
57+
BsonConverter.fromBson(aggregationResult.get("keySet").head).asInstanceOf[List[String]]
58+
}
59+
3560
protected def coll: MongoCollection[A] = collection
3661

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

4065
def importJsonFile(file: File): SingleObservable[BulkWriteResult] = {
4166
val docs = new ArrayBuffer[Document]()
42-
try {
43-
if (file.exists) {
44-
val iterator = file.lineIterator(Charset.forName("UTF-8"))
45-
iterator.foreach(line => docs.+=(DocumentHelper.documentFromJsonString(line).get))
46-
}
67+
try if (file.exists) {
68+
val iterator = file.lineIterator(Charset.forName("UTF-8"))
69+
iterator.foreach(line => docs.+=(DocumentHelper.documentFromJsonString(line).get))
4770
}
4871
catch {
4972
case e: JsonParseException =>

src/test/scala/com/sfxcode/nosql/mongo/dao/BookDAOSpec.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ class BookDAOSpec extends Specification with BeforeAll {
3434
val count: Long = BookDAO.count().result()
3535
count mustEqual 431
3636
}
37+
38+
"support columnNames" in {
39+
val columnNames = BookDAO.columnNames()
40+
columnNames.size mustEqual 11
41+
}
3742
}
3843

3944
"BookDAO Aggregation" should {

src/test/scala/com/sfxcode/nosql/mongo/dao/PersonDAOSpec.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import java.util.concurrent.TimeUnit
44

55
import com.sfxcode.nosql.MongoImplicits
66
import com.sfxcode.nosql.mongo.test.TestDatabase.PersonDAO
7-
import com.sfxcode.nosql.mongo._
87
import com.sfxcode.nosql.mongo.model.Person
98

109
import scala.concurrent.ExecutionContext.Implicits.global
@@ -20,6 +19,11 @@ class PersonDAOSpec extends PersonSpecification with MongoImplicits {
2019
count mustEqual 200
2120
}
2221

22+
"support columnNames" in {
23+
val columnNames = PersonDAO.columnNames(100)
24+
columnNames.size mustEqual 18
25+
}
26+
2327
"support results" in {
2428
val seq: Seq[Person] = PersonDAO.find()
2529
seq must haveSize(200)

0 commit comments

Comments
 (0)