Skip to content

Commit a824d33

Browse files
committed
update documentation for searching and scrolling apis
1 parent c763de7 commit a824d33

File tree

3 files changed

+85
-15
lines changed

3 files changed

+85
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ val searchResult = client.search(SQLQuery("SELECT * FROM users WHERE age > 25"))
9999
case class Product(id: String, name: String, price: Double, category: String, obsolete: Boolean)
100100

101101
// Scroll through large datasets
102-
val obsoleteProducts: Source[Product, NotUsed] = client.scrollAs[Product](
102+
val obsoleteProducts: Source[Product, NotUsed] = client.scrollAsUnchecked[Product](
103103
"""
104104
|SELECT uuid AS id, name, price, category, outdated AS obsolete FROM products WHERE outdated = true
105105
|""".stripMargin

documentation/client/scroll.md

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def scroll(
9090
)(implicit system: ActorSystem): Source[(Map[String, Any], ScrollMetrics), NotUsed]
9191

9292
// Typed scroll source (automatic deserialization)
93-
def scrollAs[T](
93+
def scrollAsUnchecked[T](
9494
sql: SQLQuery,
9595
config: ScrollConfig = ScrollConfig()
9696
)(implicit
@@ -394,7 +394,7 @@ val query = SQLQuery(
394394
)
395395

396396
// Scroll with automatic type conversion
397-
client.scrollAs[Product](query).runWith(Sink.foreach { case (product, metrics) =>
397+
client.scrollAsUnchecked[Product](query).runWith(Sink.foreach { case (product, metrics) =>
398398
println(s"Product: ${product.name} - $${product.price}")
399399
println(s"Progress: ${metrics.totalDocuments} products")
400400
})
@@ -407,7 +407,7 @@ client.scrollAs[Product](query).runWith(Sink.foreach { case (product, metrics) =
407407
```scala
408408
// Collect all products
409409
val allProducts: Future[Seq[Product]] =
410-
client.scrollAs[Product](query)
410+
client.scrollAsUnchecked[Product](query)
411411
.map(_._1) // Extract product, discard metrics
412412
.runWith(Sink.seq)
413413

@@ -425,7 +425,7 @@ allProducts.foreach { products =>
425425

426426
```scala
427427
// Filter expensive products during streaming
428-
client.scrollAs[Product](query)
428+
client.scrollAsUnchecked[Product](query)
429429
.filter { case (product, _) => product.price > 500 }
430430
.map(_._1) // Extract product
431431
.runWith(Sink.seq)
@@ -444,6 +444,30 @@ client.scrollAs[Product](query)
444444
```scala
445445
case class ProductSummary(name: String, value: Double)
446446

447+
client.scrollAsUnchecked[Product](query)
448+
.map { case (product, _) =>
449+
ProductSummary(
450+
name = product.name,
451+
value = product.price * product.stock
452+
)
453+
}
454+
.runWith(Sink.seq)
455+
.foreach { summaries =>
456+
val totalValue = summaries.map(_.value).sum
457+
println(f"Total inventory value: $$${totalValue}%,.2f")
458+
}
459+
```
460+
461+
### Validating Query at compile-time
462+
463+
```scala
464+
val query =
465+
"""
466+
SELECT id, name, price, category, stock
467+
FROM products
468+
WHERE category = 'electronics'
469+
"""
470+
447471
client.scrollAs[Product](query)
448472
.map { case (product, _) =>
449473
ProductSummary(
@@ -456,8 +480,12 @@ client.scrollAs[Product](query)
456480
val totalValue = summaries.map(_.value).sum
457481
println(f"Total inventory value: $$${totalValue}%,.2f")
458482
}
483+
)
484+
459485
```
460486

487+
📖 **[Full SQL Validation Documentation](../sql/validation.md)**
488+
461489
---
462490

463491
## Metrics and Monitoring
@@ -807,7 +835,7 @@ def commitBatch(size: Int): Future[Unit] = {
807835
case class RawProduct(id: String, name: String, price: Double)
808836
case class EnrichedProduct(id: String, name: String, price: Double, category: String, tags: Seq[String])
809837

810-
client.scrollAs[RawProduct](query)
838+
client.scrollAsUnchecked[RawProduct](query)
811839
.mapAsync(parallelism = 4) { case (raw, _) =>
812840
// Enrich each product
813841
enrichProduct(raw)
@@ -904,7 +932,7 @@ case class Statistics(
904932
)
905933
}
906934

907-
client.scrollAs[Product](query)
935+
client.scrollAsUnchecked[Product](query)
908936
.map(_._1.price) // Extract prices
909937
.fold(Statistics())(_ update _)
910938
.runWith(Sink.head)
@@ -922,7 +950,7 @@ client.scrollAs[Product](query)
922950
### Conditional Processing
923951

924952
```scala
925-
client.scrollAs[Product](query)
953+
client.scrollAsUnchecked[Product](query)
926954
.mapAsync(parallelism = 4) { case (product, _) =>
927955
product.category match {
928956
case "electronics" => processElectronics(product)
@@ -1003,7 +1031,7 @@ class ScrollApiSpec extends AsyncFlatSpec with Matchers {
10031031

10041032
// Test
10051033
query = SQLQuery(query = s"SELECT id, value FROM $testIndex")
1006-
results <- client.scrollAs[TestDoc](query).map(_._1).runWith(Sink.seq)
1034+
results <- client.scrollAsUnchecked[TestDoc](query).map(_._1).runWith(Sink.seq)
10071035

10081036
// Assertions
10091037
_ = {
@@ -1259,7 +1287,7 @@ client.scroll(query).map { case (doc, _) =>
12591287

12601288
// ✅ GOOD: Automatic type conversion
12611289
implicit val formats: Formats = DefaultFormats
1262-
client.scrollAs[Product](query)
1290+
client.scrollAsUnchecked[Product](query)
12631291
.map(_._1)
12641292
.runWith(Sink.seq)
12651293
```
@@ -1556,7 +1584,7 @@ case class ValidationResult(
15561584
)
15571585

15581586
def validateData(query: SQLQuery): Future[ValidationResult] = {
1559-
client.scrollAs[Product](query)
1587+
client.scrollAsUnchecked[Product](query)
15601588
.map(_._1)
15611589
.runWith(Sink.fold(ValidationResult(0, 0, Seq.empty)) { (result, product) =>
15621590
if (isValid(product)) {
@@ -1598,7 +1626,7 @@ case class CategoryStats(
15981626
)
15991627

16001628
def aggregateByCategory(query: SQLQuery): Future[Map[String, CategoryStats]] = {
1601-
client.scrollAs[Product](query)
1629+
client.scrollAsUnchecked[Product](query)
16021630
.map(_._1)
16031631
.runWith(Sink.fold(Map.empty[String, CategoryStats]) { (stats, product) =>
16041632
val current = stats.getOrElse(
@@ -1645,7 +1673,7 @@ case class EnrichedOrder(
16451673
)
16461674

16471675
def transformOrders(query: SQLQuery): Future[Seq[EnrichedOrder]] = {
1648-
client.scrollAs[RawOrder](query)
1676+
client.scrollAsUnchecked[RawOrder](query)
16491677
.map(_._1)
16501678
.mapAsync(parallelism = 4) { order =>
16511679
// Enrich with customer data

documentation/client/search.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
- [singleSearchAsync](#singlesearchasync)
1515
- [multiSearchAsync](#multisearchasync)
1616
- [Search with Type Conversion](#search-with-type-conversion)
17+
- [searchAsUnchecked](#searchasunchecked)
1718
- [searchAs](#searchas)
1819
- [singleSearchAs](#singlesearchas)
1920
- [multisearchAs](#multisearchas)
2021
- [Asynchronous Search with Type Conversion](#asynchronous-search-with-type-conversion)
22+
- [searchAsyncAsUnchecked](#searchasyncasunchecked)
2123
- [searchAsyncAs](#searchasyncas)
2224
- [singleSearchAsyncAs](#singlesearchasyncas)
2325
- [multiSearchAsyncAs](#multisearchasyncas)
@@ -611,7 +613,7 @@ client.multiSearchAsync(queries, Map.empty, Map.empty).foreach {
611613

612614
## Search with Type Conversion
613615

614-
### searchAs
616+
### searchAsUnchecked
615617

616618
Searches and automatically converts results to typed entities using an SQL query.
617619

@@ -706,6 +708,29 @@ val result: ElasticResult[List[EnrichedProduct]] = for {
706708

707709
---
708710

711+
### searchAs
712+
713+
Searches and automatically converts results to typed entities using an SQL query [validated at compile-time](../sql/validation.md).
714+
715+
**Signature:**
716+
717+
```scala
718+
def searchAs[U](
719+
query: String
720+
)(implicit m: Manifest[U], formats: Formats): ElasticResult[Seq[U]]
721+
```
722+
723+
**Parameters:**
724+
- `query` - SQL query
725+
- `m` - Implicit Manifest for type information
726+
- `formats` - Implicit JSON serialization formats
727+
728+
**Returns:**
729+
- `ElasticSuccess[Seq[U]]` with typed entities
730+
- `ElasticFailure` with conversion or search errors
731+
732+
---
733+
709734
### singleSearchAs
710735

711736
Searches and converts results to typed entities using an Elasticsearch query.
@@ -818,7 +843,7 @@ client.multisearchAs[Product](queries, Map.empty, Map.empty) match {
818843

819844
## Asynchronous Search with Type Conversion
820845

821-
### searchAsyncAs
846+
### searchAsyncAsUnchecked
822847

823848
Asynchronously searches and converts results to typed entities.
824849

@@ -880,6 +905,23 @@ Future.sequence(futures).map { results =>
880905
}
881906
}
882907
```
908+
---
909+
910+
### searchAsyncAs
911+
912+
Asynchronously searches and converts results to typed entities using an SQL query [validated at compile-time](../sql/validation.md).
913+
914+
**Signature:**
915+
916+
```scala
917+
def searchAsyncAs[U](
918+
query: String
919+
)(implicit
920+
m: Manifest[U],
921+
ec: ExecutionContext,
922+
formats: Formats
923+
): Future[ElasticResult[Seq[U]]]
924+
```
883925

884926
---
885927

0 commit comments

Comments
 (0)