Browse Source

move counting and query options

labs/antora
Christoph Strobl 2 years ago
parent
commit
da0d49d261
No known key found for this signature in database
GPG Key ID: 8CC1AB53391458C8
  1. 21
      src/main/antora/modules/ROOT/nav.adoc
  2. 15
      src/main/antora/modules/ROOT/pages/mongodb/mongo-json-schema.adoc
  3. 17
      src/main/antora/modules/ROOT/pages/mongodb/mongo-query/additional-options.adoc
  4. 4
      src/main/antora/modules/ROOT/pages/mongodb/mongo-query/collation.adoc
  5. 85
      src/main/antora/modules/ROOT/pages/mongodb/query-by-example.adoc
  6. 14
      src/main/antora/modules/ROOT/pages/mongodb/template-document-count.adoc
  7. 130
      src/main/antora/modules/ROOT/pages/mongodb/template-query-operations.adoc
  8. 76
      src/main/antora/modules/ROOT/pages/mongodb/template-query-options.adoc

21
src/main/antora/modules/ROOT/nav.adoc

@ -11,11 +11,13 @@ @@ -11,11 +11,13 @@
*** xref:mongodb/template-config.adoc[]
*** xref:mongodb/template-crud-operations.adoc[]
*** xref:mongodb/template-query-operations.adoc[]
**** xref:mongodb/mongo-query/geo-json.adoc[]
**** xref:mongodb/mongo-query/collation.adoc[]
**** xref:mongodb/mongo-query/kotlin-support.adoc[]
**** xref:mongodb/mongo-query/additional-options.adoc[]
*** xref:mongodb/mongo-query-count.adoc[]
**** xref:mongodb/template-query-options.adoc[]
*** xref:mongodb/template-document-count.adoc[]
*** xref:mongodb/mongo-mapreduce.adoc[]
*** xref:mongodb/mongo-server-side-scripts.adoc[]
*** xref:mongodb/mongo-group.adoc[]
@ -25,7 +27,6 @@ @@ -25,7 +27,6 @@
*** xref:mongodb/mongo-exception.adoc[]
*** xref:mongodb/mongo-executioncallback.adoc[]
** xref:mongodb/mongo-json-schema.adoc[]
** xref:mongodb/query-by-example.adoc[]
** xref:mongodb/aggregation-framework.adoc[]
** xref:mongodb/mongo-entity-callbacks.adoc[]
** xref:mongodb/gridfs.adoc[]
@ -49,3 +50,11 @@ @@ -49,3 +50,11 @@
** xref:mongodb/kotlin.adoc[]
** xref:mongodb/jmx.adoc[]
** xref:mongodb/migrating.adoc[]
** xref:mongodb/query-by-example.adoc[]
**** xref:mongodb/mongo-query/geo-json.adoc[]
**** xref:mongodb/mongo-query/collation.adoc[]
**** xref:mongodb/mongo-query/kotlin-support.adoc[]
**** xref:mongodb/mongo-query/additional-options.adoc[]

15
src/main/antora/modules/ROOT/pages/mongodb/mongo-json-schema.adoc

@ -287,21 +287,6 @@ class B extends Root { @@ -287,21 +287,6 @@ class B extends Root {
----
====
[[mongo.jsonSchema.query]]
== Query a collection for matching JSON Schema
You can use a schema to query any collection for documents that match a given structure defined by a JSON schema, as the following example shows:
.Query for Documents matching a `$jsonSchema`
====
[source,java]
----
MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();
template.find(query(matchingDocumentStructure(schema)), Person.class);
----
====
[[mongo.jsonSchema.encrypted-fields]]
== Encrypted Fields

17
src/main/antora/modules/ROOT/pages/mongodb/mongo-query/additional-options.adoc

@ -1,19 +1,4 @@ @@ -1,19 +1,4 @@
[[mongo.query.additional-query-options]]
= Additional Query Options
MongoDB offers various ways of applying meta information, like a comment or a batch size, to a query.Using the `Query` API
directly there are several methods for those options.
====
[source,java]
----
Query query = query(where("firstname").is("luke"))
.comment("find luke") <1>
.cursorBatchSize(100) <2>
----
<1> The comment propagated to the MongoDB profile log.
<2> The number of documents to return in each response batch.
====
TODO: move to repo
On the repository level the `@Meta` annotation provides means to add query options in a declarative way.

4
src/main/antora/modules/ROOT/pages/mongodb/mongo-query/collation.adoc

@ -1,7 +1,9 @@ @@ -1,7 +1,9 @@
[[mongo.collation]]
= Collations
Since version 3.4, MongoDB supports collations for collection and index creation and various query operations. Collations define string comparison rules based on the http://userguide.icu-project.org/collation/concepts[ICU collations]. A collation document consists of various properties that are encapsulated in `Collation`, as the following listing shows:
Since version 3.4, MongoDB supports collations for collection and index creation and various query operations.
Collations define string comparison rules based on the http://userguide.icu-project.org/collation/concepts[ICU collations].
A collation document consists of various properties that are encapsulated in `Collation`, as the following listing shows:
====
[source,java]

85
src/main/antora/modules/ROOT/pages/mongodb/query-by-example.adoc

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@
[[query-by-example.running]]
= Running an Example
TODO: move this section to the repositories documentation
The following example shows how to query by example when using a repository (of `Person` objects, in this case):
.Query by Example using a repository
@ -21,86 +23,3 @@ public class PersonService { @@ -21,86 +23,3 @@ public class PersonService {
}
----
====
An `Example` containing an untyped `ExampleSpec` uses the Repository type and its collection name. Typed `ExampleSpec` instances use their type as the result type and the collection name from the `Repository` instance.
NOTE: When including `null` values in the `ExampleSpec`, Spring Data Mongo uses embedded document matching instead of dot notation property matching. Doing so forces exact document matching for all property values and the property order in the embedded document.
Spring Data MongoDB provides support for the following matching options:
[cols="1,2", options="header"]
.`StringMatcher` options
|===
| Matching
| Logical result
| `DEFAULT` (case-sensitive)
| `{"firstname" : firstname}`
| `DEFAULT` (case-insensitive)
| `{"firstname" : { $regex: firstname, $options: 'i'}}`
| `EXACT` (case-sensitive)
| `{"firstname" : { $regex: /^firstname$/}}`
| `EXACT` (case-insensitive)
| `{"firstname" : { $regex: /^firstname$/, $options: 'i'}}`
| `STARTING` (case-sensitive)
| `{"firstname" : { $regex: /^firstname/}}`
| `STARTING` (case-insensitive)
| `{"firstname" : { $regex: /^firstname/, $options: 'i'}}`
| `ENDING` (case-sensitive)
| `{"firstname" : { $regex: /firstname$/}}`
| `ENDING` (case-insensitive)
| `{"firstname" : { $regex: /firstname$/, $options: 'i'}}`
| `CONTAINING` (case-sensitive)
| `{"firstname" : { $regex: /.\*firstname.*/}}`
| `CONTAINING` (case-insensitive)
| `{"firstname" : { $regex: /.\*firstname.*/, $options: 'i'}}`
| `REGEX` (case-sensitive)
| `{"firstname" : { $regex: /firstname/}}`
| `REGEX` (case-insensitive)
| `{"firstname" : { $regex: /firstname/, $options: 'i'}}`
|===
[[query-by-example.untyped]]
= Untyped Example
By default `Example` is strictly typed. This means that the mapped query has an included type match, restricting it to probe assignable types. For example, when sticking with the default type key (`_class`), the query has restrictions such as (`_class : { $in : [ com.acme.Person] }`).
By using the `UntypedExampleMatcher`, it is possible to bypass the default behavior and skip the type restriction. So, as long as field names match, nearly any domain type can be used as the probe for creating the reference, as the following example shows:
.Untyped Example Query
====
[source, java]
----
class JustAnArbitraryClassWithMatchingFieldName {
@Field("lastname") String value;
}
JustAnArbitraryClassWithMatchingFieldNames probe = new JustAnArbitraryClassWithMatchingFieldNames();
probe.value = "stark";
Example example = Example.of(probe, UntypedExampleMatcher.matching());
Query query = new Query(new Criteria().alike(example));
List<Person> result = template.find(query, Person.class);
----
====
[NOTE]
====
`UntypedExampleMatcher` is likely the right choice for you if you are storing different entities within a single collection or opted out of writing xref:reference/mongodb/mongo-template-save-update-remove.adoc#mongo-template.type-mapping[type hints].
Also, keep in mind that using `@TypeAlias` requires eager initialization of the `MappingContext`. To do so, configure `initialEntitySet` to to ensure proper alias resolution for read operations.
====

14
src/main/antora/modules/ROOT/pages/mongodb/mongo-query-count.adoc → src/main/antora/modules/ROOT/pages/mongodb/template-document-count.adoc

@ -1,8 +1,20 @@ @@ -1,8 +1,20 @@
[[mongo.query.count]]
= Counting Documents
The template API offers various methods to count the number of documents matching a given criteria.
One of them outlined below.
====
[source,java]
----
template.query(Person.class)
.matching(query(where("firstname").is("luke")))
.count();
----
====
In pre-3.x versions of SpringData MongoDB the count operation used MongoDBs internal collection statistics.
With the introduction of xref:reference/client-session-transactions.adoc#mongo.transactions[MongoDB Transactions] this was no longer possible because statistics would not correctly reflect potential changes during a transaction requiring an aggregation-based count approach.
With the introduction of xref:mongodb/client-session-transactions.adoc#mongo.transactions[MongoDB Transactions] this was no longer possible because statistics would not correctly reflect potential changes during a transaction requiring an aggregation-based count approach.
So in version 2.x `MongoOperations.count()` would use the collection statistics if no transaction was in progress, and the aggregation variant if so.
As of Spring Data MongoDB 3.x any `count` operation uses regardless the existence of filter criteria the aggregation-based count approach via MongoDBs `countDocuments`.

130
src/main/antora/modules/ROOT/pages/mongodb/template-query-operations.adoc

@ -96,11 +96,11 @@ The `Criteria` class provides the following methods, all of which correspond to @@ -96,11 +96,11 @@ The `Criteria` class provides the following methods, all of which correspond to
* `Criteria` *sampleRate* `(double sampleRate)` Creates a criterion using the `$sampleRate` operator
* `Criteria` *size* `(int s)` Creates a criterion using the `$size` operator
* `Criteria` *type* `(int t)` Creates a criterion using the `$type` operator
* `Criteria` *matchingDocumentStructure* `(MongoJsonSchema schema)` Creates a criterion using the `$jsonSchema` operator for xref:reference/mongo-json-schema.adoc[JSON schema criteria]. `$jsonSchema` can only be applied on the top level of a query and not property specific. Use the `properties` attribute of the schema to match against nested fields.
* `Criteria` *matchingDocumentStructure* `(MongoJsonSchema schema)` Creates a criterion using the `$jsonSchema` operator for xref:mongodb/mongo-json-schema.adoc[JSON schema criteria]. `$jsonSchema` can only be applied on the top level of a query and not property specific. Use the `properties` attribute of the schema to match against nested fields.
* `Criteria` *bits()* is the gateway to https://docs.mongodb.com/manual/reference/operator/query-bitwise/[MongoDB bitwise query operators] like `$bitsAllClear`.
The Criteria class also provides the following methods for geospatial queries (see the xref:reference/mongodb/mongo-query/geospatial.adoc[GeoSpatial Queries] section to see them in action):
The Criteria class also provides the following methods for geospatial queries.
* `Criteria` *within* `(Circle circle)` Creates a geospatial criterion using `$geoWithin $center` operators.
* `Criteria` *within* `(Box box)` Creates a geospatial criterion using a `$geoWithin $box` operation.
@ -184,7 +184,7 @@ query.fields() @@ -184,7 +184,7 @@ query.fields()
<4> Use SpEL along with an `AggregationExpression` to invoke expression functions. Field names are mapped to the ones used in the domain model.
====
`@Query(fields="…")` allows usage of expression field projections at `Repository` level as described in xref:reference/mongo-repositories.adoc#mongodb.repositories.queries.json-based[MongoDB JSON-based Query Methods and Field Restriction].
`@Query(fields="…")` allows usage of expression field projections at `Repository` level as described in xref:mongodb/mongo-repositories.adoc#mongodb.repositories.queries.json-based[MongoDB JSON-based Query Methods and Field Restriction].
[[mongo-template.query.distinct]]
== Query Distinct Values
@ -230,7 +230,7 @@ template.query(Person.class) <1> @@ -230,7 +230,7 @@ template.query(Person.class) <1>
MongoDB supports GeoSpatial queries through the use of operators such as `$near`, `$within`, `geoWithin`, and `$nearSphere`. Methods specific to geospatial queries are available on the `Criteria` class. There are also a few shape classes (`Box`, `Circle`, and `Point`) that are used in conjunction with geospatial related `Criteria` methods.
NOTE: Using GeoSpatial queries requires attention when used within MongoDB transactions, see xref:reference/client-session-transactions.adoc#mongo.transactions.behavior[Special behavior inside transactions].
NOTE: Using GeoSpatial queries requires attention when used within MongoDB transactions, see xref:mongodb/client-session-transactions.adoc#mongo.transactions.behavior[Special behavior inside transactions].
To understand how to perform GeoSpatial queries, consider the following `Venue` class (taken from the integration tests and relying on the rich `MappingMongoConverter`):
@ -723,3 +723,125 @@ TextQuery.queryText(new TextCriteria().phrase("coffee cake")); @@ -723,3 +723,125 @@ TextQuery.queryText(new TextCriteria().phrase("coffee cake"));
You can set flags for `$caseSensitive` and `$diacriticSensitive` by using the corresponding methods on `TextCriteria`.
Note that these two optional flags have been introduced in MongoDB 3.2 and are not included in the query unless explicitly set.
[[mongo.query-by-example]]
== Query by Example
Some general information about Query By Example support in Spring Data can be found in the commons documentation.
The following snipped shows how to query by example:
.Typed Example Query
[source,java]
----
Person probe = new Person();
probe.lastname = "stark";
Example example = Example.of(probe);
Query query = new Query(new Criteria().alike(example));
List<Person> result = template.find(query, Person.class);
----
By default `Example` is strictly typed. This means that the mapped query has an included type match, restricting it to probe assignable types.
For example, when sticking with the default type key (`_class`), the query has restrictions such as (`_class : { $in : [ com.acme.Person] }`).
By using the `UntypedExampleMatcher`, it is possible to bypass the default behavior and skip the type restriction. So, as long as field names match, nearly any domain type can be used as the probe for creating the reference, as the following example shows:
.Untyped Example Query
====
[source, java]
----
class JustAnArbitraryClassWithMatchingFieldName {
@Field("lastname") String value;
}
JustAnArbitraryClassWithMatchingFieldNames probe = new JustAnArbitraryClassWithMatchingFieldNames();
probe.value = "stark";
Example example = Example.of(probe, UntypedExampleMatcher.matching());
Query query = new Query(new Criteria().alike(example));
List<Person> result = template.find(query, Person.class);
----
====
[NOTE]
====
When including `null` values in the `ExampleSpec`, Spring Data Mongo uses embedded document matching instead of dot notation property matching.
Doing so forces exact document matching for all property values and the property order in the embedded document.
====
[NOTE]
====
`UntypedExampleMatcher` is likely the right choice for you if you are storing different entities within a single collection or opted out of writing xref:mongodb/mongodb/mongo-template-save-update-remove.adoc#mongo-template.type-mapping[type hints].
Also, keep in mind that using `@TypeAlias` requires eager initialization of the `MappingContext`. To do so, configure `initialEntitySet` to to ensure proper alias resolution for read operations.
====
Spring Data MongoDB provides support for the following matching options:
[cols="1,2", options="header"]
.`StringMatcher` options
|===
| Matching
| Logical result
| `DEFAULT` (case-sensitive)
| `{"firstname" : firstname}`
| `DEFAULT` (case-insensitive)
| `{"firstname" : { $regex: firstname, $options: 'i'}}`
| `EXACT` (case-sensitive)
| `{"firstname" : { $regex: /^firstname$/}}`
| `EXACT` (case-insensitive)
| `{"firstname" : { $regex: /^firstname$/, $options: 'i'}}`
| `STARTING` (case-sensitive)
| `{"firstname" : { $regex: /^firstname/}}`
| `STARTING` (case-insensitive)
| `{"firstname" : { $regex: /^firstname/, $options: 'i'}}`
| `ENDING` (case-sensitive)
| `{"firstname" : { $regex: /firstname$/}}`
| `ENDING` (case-insensitive)
| `{"firstname" : { $regex: /firstname$/, $options: 'i'}}`
| `CONTAINING` (case-sensitive)
| `{"firstname" : { $regex: /.\*firstname.*/}}`
| `CONTAINING` (case-insensitive)
| `{"firstname" : { $regex: /.\*firstname.*/, $options: 'i'}}`
| `REGEX` (case-sensitive)
| `{"firstname" : { $regex: /firstname/}}`
| `REGEX` (case-insensitive)
| `{"firstname" : { $regex: /firstname/, $options: 'i'}}`
|===
[[mongo.jsonSchema.query]]
== Query a collection for matching JSON Schema
You can use a schema to query any collection for documents that match a given structure defined by a JSON schema, as the following example shows:
.Query for Documents matching a `$jsonSchema`
====
[source,java]
----
MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();
template.find(query(matchingDocumentStructure(schema)), Person.class);
----
====
Please refer to the xref:mongodb/mongo-json-schema.adoc[JSON Schema] section to learn more about the schema support in Spring Data MongoDB.

76
src/main/antora/modules/ROOT/pages/mongodb/template-query-options.adoc

@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
[[mongo.query.additional-query-options]]
== Additional Query Options
MongoDB offers various ways of applying meta information, like a comment or a batch size, to a query.Using the `Query` API
directly there are several methods for those options.
=== Hints
Index hints can be applied in two ways, using the index name or its field definition.
====
[source,java]
----
template.query(Person.class)
.matching(query("...").withHint("index-to-use"));
template.query(Person.class)
.matching(query("...").withHint("{ firstname : 1 }"));
----
====
=== Cursor Batch Size
The cursor batch size defines the number of documents to return in each response batch.
====
[source,java]
----
Query query = query(where("firstname").is("luke"))
.cursorBatchSize(100)
----
====
=== Collations
Using collations with collection operations is a matter of specifying a `Collation` instance in your query or operation options, as the following two examples show:
====
[source,java]
----
Collation collation = Collation.of("de");
Query query = new Query(Criteria.where("firstName").is("Amél"))
.collation(collation);
List<Person> results = template.find(query, Person.class);
----
====
=== Read Preference
The `ReadPreference` to use can be set directly on the `Query` object to be run as outlined below.
====
[source,java]
----
template.find(Person.class)
.matching(query(where(...)).withReadPreference(ReadPreference.secondary()))
.all();
----
====
NOTE: The preference set on the `Query` instance will supersede the default `ReadPreference` of `MongoTemplate`.
=== Comments
Queries can be equipped with comments which makes them easier to look up in server logs.
====
[source,java]
----
template.find(Person.class)
.matching(query(where(...)).comment("Use the force luke!"))
.all();
----
====
Loading…
Cancel
Save