From dda149d9fb93eb41b4f21aeb8d4a080617820a10 Mon Sep 17 00:00:00 2001 From: kirill5k Date: Wed, 3 Jul 2024 22:53:31 +0100 Subject: [PATCH] Implement meta Projections --- .../mongo4cats/operations/Aggregate.scala | 8 +-- .../mongo4cats/operations/Projection.scala | 68 ++++++++++++------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/modules/kernel/src/main/scala/mongo4cats/operations/Aggregate.scala b/modules/kernel/src/main/scala/mongo4cats/operations/Aggregate.scala index 869530e9..b8b5bcee 100644 --- a/modules/kernel/src/main/scala/mongo4cats/operations/Aggregate.scala +++ b/modules/kernel/src/main/scala/mongo4cats/operations/Aggregate.scala @@ -378,8 +378,8 @@ trait Aggregate extends AsJava { def geoNear(point: Point, distanceField: String, options: GeoNearOptions): Aggregate def geoNear(point: Point, distanceField: String): Aggregate = geoNear(point, distanceField, GeoNearOptions.geoNearOptions()) - /** Creates a \$search pipeline stage supported by MongoDB Atlas. You may use \$meta: "searchScore", e.g., via metaSearchScore ( String ) - * in Projection, to extract the relevance score assigned to each found document. + /** Creates a \$search pipeline stage supported by MongoDB Atlas. You may use \$meta: "searchScore", e.g., via + * Projection.metaSearchScore(String), to extract the relevance score assigned to each found document. * @param operator * A search operator. * @param options @@ -389,8 +389,8 @@ trait Aggregate extends AsJava { def search(operator: SearchOperator, options: SearchOptions): Aggregate def search(operator: SearchOperator): Aggregate = search(operator, SearchOptions.searchOptions()) - /** Creates a \$search pipeline stage supported by MongoDB Atlas. You may use \$meta: "searchScore", e.g., via metaSearchScore ( String ) - * in Projection, to extract the relevance score assigned to each found document. + /** Creates a \$search pipeline stage supported by MongoDB Atlas. You may use \$meta: "searchScore", e.g., via + * Projection.metaSearchScore(String), to extract the relevance score assigned to each found document. * @param collector * A search collector. * @param options diff --git a/modules/kernel/src/main/scala/mongo4cats/operations/Projection.scala b/modules/kernel/src/main/scala/mongo4cats/operations/Projection.scala index da80fd2c..2e20c6ff 100644 --- a/modules/kernel/src/main/scala/mongo4cats/operations/Projection.scala +++ b/modules/kernel/src/main/scala/mongo4cats/operations/Projection.scala @@ -122,6 +122,30 @@ trait Projection { */ def metaTextScore(fieldName: String): Projection + /** Creates a projection to the given field name of the searchScore, for use with Aggregate.search(SearchOperator,SearchOptions) / + * Aggregate.search(SearchCollector,SearchOptions). Calling this method is equivalent to calling meta(String,String) with "searchScore" + * as the second argument. + * + * @param fieldName + * the field name + * @return + * the projection + * @since 4.7 + */ + def metaSearchScore(fieldName: String): Projection + + /** Creates a projection to the given field name of the searchHighlights, for use with Aggregate.search(SearchOperator,SearchOptions) / + * Aggregates.search(SearchCollector,SearchOptions). Calling this method is equivalent to calling meta String,String) with + * "searchHighlights" as the second argument. + * + * @param fieldName + * the field name + * @return + * the projection + * @since 4.7 + */ + def metaSearchHighlights(fieldName: String): Projection + /** Creates a projection to the given field name of a slice of the array value of that field. * * @param fieldName @@ -162,31 +186,21 @@ trait Projection { object Projection { private val empty: Projection = ProjectionBuilder(Nil) - def computed[T](fieldName: String, expression: T): Projection = empty.computed(fieldName, expression) - - def include(fieldName: String): Projection = empty.include(fieldName) - - def include(fieldNames: Seq[String]): Projection = empty.include(fieldNames) - - def exclude(fieldName: String): Projection = empty.exclude(fieldName) - - def exclude(fieldNames: Seq[String]): Projection = empty.exclude(fieldNames) - - def excludeId: Projection = empty.excludeId - - def elemMatch(fieldName: String): Projection = empty.elemMatch(fieldName) - - def elemMatch(fieldName: String, filter: Filter): Projection = empty.elemMatch(fieldName, filter) - - def meta(fieldName: String, metaFieldName: String): Projection = empty.meta(fieldName, metaFieldName) - - def metaTextScore(fieldName: String): Projection = empty.metaTextScore(fieldName) - - def slice(fieldName: String, limit: Int): Projection = empty.slice(fieldName, limit) - + def computed[T](fieldName: String, expression: T): Projection = empty.computed(fieldName, expression) + def include(fieldName: String): Projection = empty.include(fieldName) + def include(fieldNames: Seq[String]): Projection = empty.include(fieldNames) + def exclude(fieldName: String): Projection = empty.exclude(fieldName) + def exclude(fieldNames: Seq[String]): Projection = empty.exclude(fieldNames) + def excludeId: Projection = empty.excludeId + def elemMatch(fieldName: String): Projection = empty.elemMatch(fieldName) + def elemMatch(fieldName: String, filter: Filter): Projection = empty.elemMatch(fieldName, filter) + def meta(fieldName: String, metaFieldName: String): Projection = empty.meta(fieldName, metaFieldName) + def metaTextScore(fieldName: String): Projection = empty.metaTextScore(fieldName) + def metaSearchScore(fieldName: String): Projection = empty.metaSearchScore(fieldName) + def metaSearchHighlights(fieldName: String): Projection = empty.metaSearchHighlights(fieldName) + def slice(fieldName: String, limit: Int): Projection = empty.slice(fieldName, limit) def slice(fieldName: String, skip: Int, limit: Int): Projection = empty.slice(fieldName, skip, limit) - - def combinedWith(anotherProjection: Projection): Projection = empty.combinedWith(anotherProjection) + def combinedWith(anotherProjection: Projection): Projection = empty.combinedWith(anotherProjection) } final private case class ProjectionBuilder( @@ -223,6 +237,12 @@ final private case class ProjectionBuilder( override def metaTextScore(fieldName: String): Projection = ProjectionBuilder(Projections.metaTextScore(fieldName) :: projections) + override def metaSearchScore(fieldName: String): Projection = + ProjectionBuilder(Projections.metaSearchScore(fieldName) :: projections) + + override def metaSearchHighlights(fieldName: String): Projection = + ProjectionBuilder(Projections.metaSearchHighlights(fieldName) :: projections) + override def slice(fieldName: String, limit: Int): Projection = { val sliceCommand = Document("$slice" := BsonValue.array(BsonValue.string("$" + fieldName), BsonValue.int(limit))) val sliceProjection = Document(fieldName := sliceCommand)