Skip to content

Commit 1fe1d8b

Browse files
author
QuadStingray
committed
feat: Foreach in Pagination Result
1 parent 5f3134d commit 1fe1d8b

File tree

14 files changed

+177
-33
lines changed

14 files changed

+177
-33
lines changed

build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ libraryDependencies += "org.xerial.snappy" % "snappy-java" % "1.1.9.1" % Provide
8181

8282
libraryDependencies += "com.github.luben" % "zstd-jni" % "1.5.4-2" % Provided
8383

84+
// #region lucene-dependency
8485
libraryDependencies += "org.apache.lucene" % "lucene-queryparser" % "9.5.0" % Provided
86+
// #endregion lucene-dependency
8587

8688
val MongoJavaServerVersion = "1.43.0"
8789

docs/.vitepress/config.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ function nav() {
5757
{text: 'MongoDAO', link: '/documentation/mongo-dao/'},
5858
{text: 'GridFsDAO', link: '/documentation/gridfs-dao/'},
5959
{text: 'Collection', link: '/documentation/collection/'},
60-
{text: 'LocalServer', link: '/documentation/local-server'},
61-
// { text: 'Configuration', link: '/guide/configuration' },
60+
{text: 'LocalServer', link: '/documentation/local-server'}
6261
]
6362
},
6463
{
@@ -86,12 +85,13 @@ function sidebarDocumentation() {
8685
collapsible: true,
8786
collapsed: true,
8887
items: [
89-
{ text: 'Introduction', link: '/documentation/database/' },
90-
{ text: 'Mongo Config', link: 'documentation/database/config' },
91-
{ text: 'DatabaseProvider', link: 'documentation/database/provider' },
92-
{ text: 'Reactive Streams', link: 'documentation/database/reactive-streams' },
93-
{ text: 'Bson', link: 'documentation/database/bson' },
94-
{ text: 'Relationships', link: 'documentation/database/relationships' },
88+
{text: 'Introduction', link: '/documentation/database/'},
89+
{text: 'Mongo Config', link: 'documentation/database/config'},
90+
{text: 'DatabaseProvider', link: 'documentation/database/provider'},
91+
{text: 'Reactive Streams', link: 'documentation/database/reactive-streams'},
92+
{text: 'Bson', link: 'documentation/database/bson'},
93+
{text: 'Relationships', link: 'documentation/database/relationships'},
94+
{text: 'Lucene Query', link: '/documentation/database/lucene'}
9595
]
9696
},
9797
{
@@ -100,10 +100,10 @@ function sidebarDocumentation() {
100100
collapsible: true,
101101
collapsed: true,
102102
items: [
103-
{ text: 'Introduction', link: '/documentation/mongo-dao/' },
104-
{ text: 'MongoDAO Base', link: '/documentation/mongo-dao/base' },
105-
{ text: 'CRUD Functions', link: '/documentation/mongo-dao/crud' },
106-
{ text: 'Search Functions', link: '/documentation/mongo-dao/search' }
103+
{text: 'Introduction', link: '/documentation/mongo-dao/'},
104+
{text: 'MongoDAO Base', link: '/documentation/mongo-dao/base'},
105+
{text: 'CRUD Functions', link: '/documentation/mongo-dao/crud'},
106+
{text: 'Search Functions', link: '/documentation/mongo-dao/search'}
107107
]
108108
},
109109
{
@@ -112,9 +112,9 @@ function sidebarDocumentation() {
112112
collapsible: true,
113113
collapsed: true,
114114
items: [
115-
{ text: 'Introduction', link: '/documentation/gridfs-dao/' },
116-
{ text: 'CRUD Functions', link: '/documentation/gridfs-dao/crud' },
117-
{ text: 'Metadata', link: '/documentation/gridfs-dao/metadata' }
115+
{text: 'Introduction', link: '/documentation/gridfs-dao/'},
116+
{text: 'CRUD Functions', link: '/documentation/gridfs-dao/crud'},
117+
{text: 'Metadata', link: '/documentation/gridfs-dao/metadata'}
118118
]
119119
},
120120
{
@@ -123,8 +123,9 @@ function sidebarDocumentation() {
123123
collapsible: true,
124124
collapsed: true,
125125
items: [
126-
{ text: 'Introduction', link: '/documentation/collection/' },
127-
{ text: 'Aggregation', link: '/documentation/collection/aggregation' }
126+
{text: 'Introduction', link: '/documentation/collection/'},
127+
{text: 'Aggregation', link: '/documentation/collection/aggregation'},
128+
{text: 'Pagination', link: '/documentation/collection/pagination'}
128129
]
129130
},
130131
{
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Pagination
2+
3+
In many cases you want to have the possibility to paginate over the response of your query result. MongoCamp MongoDB Driver support the pagination over Aggregation and Filter Response. As well there is an comfort methode to have an foreach over the whole Response, but with pagination to have a lower memory footprint.
4+
5+
## Aggregation Pagination
6+
7+
::: warning
8+
The Pagination over an aggregation pipeline supports only the response of `Document`, also if you use an case class MongoDAO you will got an `Document` back.
9+
:::
10+
11+
<<< @/../src/test/scala/dev/mongocamp/driver/mongodb/pagination/PaginationAggregationSpec.scala#aggregation-pagination
12+
13+
## Find Pagination
14+
15+
<<< @/../src/test/scala/dev/mongocamp/driver/mongodb/pagination/PaginationFilterSpec.scala#filter-pagination
16+
17+
## Foreach over Pagination result
18+
19+
<<< @/../src/test/scala/dev/mongocamp/driver/mongodb/pagination/PaginationIterationSpec.scala#aggregation-foreach
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Lucene Query
2+
3+
MongoCamp Mongo Driver support the usage of [Lucene Query](https://lucene.apache.org/) to search in the MongoDb.
4+
5+
## Usage
6+
Fist you have the add the lucene-queryparser Dependency to your build.sbt (without the provided marker).
7+
8+
<<< @/../build.sbt#lucene-dependency{scala}
9+
10+
### Explicit Usage
11+
The LuceneConverter has the methods to parse a String to and `Query` and a other to the document conversion.
12+
13+
<<< @/../src/test/scala/dev/mongocamp/driver/mongodb/lucene/LuceneSearchSpec.scala#lucene-parser-with-explicit
14+
15+
### Implicit Usage
16+
Like the Map to Bson conversion there is also an implicit method to convert `Query` to find Bson.
17+
18+
<<< @/../src/test/scala/dev/mongocamp/driver/mongodb/lucene/LuceneSearchSpec.scala#lucene-parser-with-implicit
19+
20+
## Read More
21+
[Lucene Cheatsheet](https://www.lucenetutorial.com/lucene-query-syntax.html)

docs/index.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,15 @@ features:
2121
details: Easy Database Config with provider and MongoConfig
2222
- title: DAO Pattern
2323
details: Implement the DAO Pattern for simple MongoDB usage [MongoDAO.
24-
- title: GridFS Support
24+
- title: Pagination
25+
details: Use Pagination in your MongoDB for a lower RAM needing over large responses.
2526
- title: Enhanced BSON
27+
details: Implicit Conversion from Scala Map to BSON
28+
- title: GridFS Support
29+
details: It provides easy upload, download and metadata handling.
2630
- title: Reactive Streams
31+
details: The MongoDB Scala driver is built upon Reactive Streams.
2732
- title: Relationships
33+
details: Sometimes there is a need for relationsips beetween collections, now you can have it.
34+
- title: Lucene Query
35+
details: Use Apache Lucene Query Language in MongoDb
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package dev.mongocamp.driver.mongodb
22

33
import org.bson.conversions.Bson
4-
import org.mongodb.scala.model.Sorts.{ ascending, descending, orderBy }
4+
import org.mongodb.scala.model.Sorts.{ascending, descending, orderBy}
55

66
object Sort extends Sort
77

88
trait Sort {
99

1010
def sortByKey(key: String, sortAscending: Boolean = true): Bson =
11-
if (sortAscending)
11+
if (sortAscending) {
1212
orderBy(ascending(key))
13-
else
13+
}
14+
else {
1415
orderBy(descending(key))
16+
}
1517

1618
}

src/main/scala/dev/mongocamp/driver/mongodb/operation/Search.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import org.bson.BsonValue
77
import org.mongodb.scala.bson.ObjectId
88
import org.mongodb.scala.bson.conversions.Bson
99
import org.mongodb.scala.model.Filters._
10-
import org.mongodb.scala.{ AggregateObservable, DistinctObservable, Document, FindObservable, MongoCollection }
10+
import org.mongodb.scala.{AggregateObservable, DistinctObservable, Document, FindObservable, MongoCollection}
1111

1212
import scala.reflect.ClassTag
1313

@@ -21,10 +21,12 @@ abstract class Search[A]()(implicit ct: ClassTag[A]) extends Base[A] {
2121
projection: Bson = Document(),
2222
limit: Int = 0
2323
): FindObservable[A] =
24-
if (limit > 0)
24+
if (limit > 0) {
2525
coll.find(filter).sort(sort).projection(projection).limit(limit)
26-
else
26+
}
27+
else {
2728
coll.find(filter).sort(sort).projection(projection)
29+
}
2830

2931
def findById(oid: ObjectId): FindObservable[A] = find(equal(DatabaseProvider.ObjectIdKey, oid))
3032

src/main/scala/dev/mongocamp/driver/mongodb/pagination/MongoPaginatedAggregation.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ import scala.jdk.CollectionConverters._
1212
case class MongoPaginatedAggregation[A <: Any](
1313
dao: MongoDAO[A],
1414
aggregationPipeline: List[Bson] = List(),
15-
allowDiskUse: Boolean = false,
16-
) {
15+
allowDiskUse: Boolean = false
16+
) extends MongoPagination[Document] {
1717

1818
private val AggregationKeyMetaData = "metadata"
1919
private val AggregationKeyData = "data"
2020
private val AggregationKeyMetaDataTotal = "total"
2121

22-
def paginate(page: Long, rows: Long): PaginationResult[org.bson.BsonDocument] = {
22+
def paginate(page: Long, rows: Long): PaginationResult[Document] = {
2323
if (rows <= 0) {
2424
throw MongoCampPaginationException("rows per page must be greater then 0.")
2525
}
@@ -41,7 +41,7 @@ case class MongoPaginatedAggregation[A <: Any](
4141

4242
val count: Long = dbResponse.get(AggregationKeyMetaData).get.asArray().get(0).asDocument().get(AggregationKeyMetaDataTotal).asNumber().longValue()
4343
val allPages = Math.ceil(count.toDouble / rows).toInt
44-
val list = dbResponse.get("data").get.asArray().asScala.map(_.asDocument())
44+
val list = dbResponse.get("data").get.asArray().asScala.map(_.asDocument()).map(bdoc => Document(bdoc) )
4545
PaginationResult(list.toList, PaginationInfo(count, rows, page, allPages))
4646
}
4747

src/main/scala/dev/mongocamp/driver/mongodb/pagination/MongoPaginatedFilter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import dev.mongocamp.driver.mongodb.exception.MongoCampPaginationException
44
import dev.mongocamp.driver.mongodb.{MongoDAO, _}
55
import org.mongodb.scala.bson.conversions.Bson
66

7-
case class MongoPaginatedFilter[A <: Any](dao: MongoDAO[A], filter: Bson = Map(), sort: Bson = Map(), projection: Bson = Map()) {
7+
case class MongoPaginatedFilter[A <: Any](dao: MongoDAO[A], filter: Bson = Map(), sort: Bson = Map(), projection: Bson = Map()) extends MongoPagination[A] {
88

99
def paginate(page: Long, rows: Long): PaginationResult[A] = {
1010
val count = countResult
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dev.mongocamp.driver.mongodb.pagination
2+
3+
trait MongoPagination[A <: Any] {
4+
def paginate(page: Long, rows: Long): PaginationResult[A]
5+
def countResult: Long
6+
}
7+
object MongoPagination {
8+
def foreach[A <: Any](pagination: MongoPagination[A], rows: Int = 50)(a: A => Unit): Unit = {
9+
var currentPageNumber = 1
10+
val rowsPerPage = if (rows < 1) Int.MaxValue else rows
11+
val maxPages = Math.ceil(pagination.countResult.toDouble / rowsPerPage).toInt
12+
while (currentPageNumber > 0 && rowsPerPage > 0 && currentPageNumber <= maxPages) {
13+
val page = pagination.paginate(currentPageNumber, rowsPerPage)
14+
page.databaseObjects.foreach(a)
15+
currentPageNumber += 1
16+
}
17+
18+
}
19+
20+
}

0 commit comments

Comments
 (0)