Querying Documents
-
Querying Documents
-
Projection
-
Selecting fields
-
Additional Query Options
-
Hints
-
Cursor Batch Size
-
Collations
-
Read Preference
-
Comments
-
Query Distinct Values
-
GeoSpatial Queries
-
geoNear Queries
-
GeoJSON Support
-
Metrics and Distance calculation
-
Full-text Search
-
Query by Example :description: Spring Data MongoDB 提供了 Query 和 Criteria 类来创建查询。这些类提供了一致的、流畅的 API,支持嵌套谓词和 MongoDB 操作符。可以使用 Query 类来指定过滤条件、排序、字段选择以及其他查询选项。Criteria 类提供了一种链式、流畅的方式来构建复杂条件,包括相等、比较和布尔运算。
您可以使用 Query
和 Criteria
类来表达您的查询。它们的函数名称反映了本地 MongoDB 运算符名称,例如 lt
、lte
、is
等。Query
和 Criteria
类遵循流畅的 API 样式,以便您可以将多个方法条件和查询链接在一起,同时拥有易于理解的代码。为提高可读性,静态导入使您可以避免使用“new”关键字创建 Query
和 Criteria
实例。您还可以使用 BasicQuery
从纯 JSON 字符串创建 Query
实例,如下例所示:
.Creating a Query instance from a plain JSON String
BasicQuery query = new BasicQuery("{ age : { $lt : 50 }, accounts.balance : { $gt : 1000.00 }}");
List<Person> result = mongoTemplate.find(query, Person.class);
Querying Documents in a Collection
先前,我们已经看到如何使用 MongoTemplate
上的 findOne
和 findById
函数检索单个文档。这些方法返回一个单一域对象,或者使用响应性 API 返回一个发出单个元素的 Mono
。我们还可以查询要返回为域对象列表的文档集合。假设我们有一些名称和年龄存储在集合中作为文档的 Person
对象,并且每个人都有一个嵌入了余额的帐户文档,那么我们现在可以使用以下代码运行查询:
-
Imperative
-
Reactive
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
// ...
List<Person> result = template.query(Person.class)
.matching(query(where("age").lt(50).and("accounts.balance").gt(1000.00d)))
.all();
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
// ...
Flux<Person> result = template.query(Person.class)
.matching(query(where("age").lt(50).and("accounts.balance").gt(1000.00d)))
.all();
所有 find 函数都将 Query
对象作为参数。这个对象定义了用来执行查询的条件和选项。使用一个静态工厂函数名为 where
的 Criteria
对象来指定条件以实例化一个新的 Criteria
对象。我们建议对 org.springframework.data.mongodb.core.query.Criteria.where
和 Query.query
使用静态导入以使查询更具可读性。
查询应该返回满足指定条件的 Person
对象的 List
或 Flux
。本节的其余部分列出了 Criteria
和 Query
类的对应于 MongoDB 中提供的运算符的方法。大多数方法返回 Criteria
对象,以便为 API 提供流畅的样式。
Criteria
类提供以下方法,它们都对应 MongoDB 中的操作符:
-
Criteria
all(Object o)
使用$all
运算符创建一个标准 -
Criteria
and(String key)
向当前Criteria
添加一个带有指定key
的链接Criteria
,并返回新创建的那个 -
Criteria
andOperator(Criteria… criteria)
对所有提供的标准使用$and
运算符创建一个与查询(需要 MongoDB 2.0 或更高版本) -
Criteria
andOperator(Collection<Criteria> criteria)
对所有提供的标准使用$and
运算符创建一个与查询(需要 MongoDB 2.0 或更高版本) -
Criteria
elemMatch(Criteria c)
使用$elemMatch
运算符创建一个标准 -
Criteria
exists(boolean b)
使用$exists
运算符创建一个标准 -
Criteria
gt(Object o)
使用$gt
运算符创建一个标准 -
Criteria
gte(Object o)
使用$gte
运算符创建一个标准 -
Criteria
in(Object… o)
为 varargs 参数创建一个使用$in
运算符的标准 -
Criteria
in(Collection<?> collection)
使用集合创建一个使用$in
运算符的标准 -
Criteria
is(Object o)
创建一个使用字段匹配({ key:value }
)的标准。如果指定的值是一个文档,则文档中的字段顺序和确切相等很重要。 -
Criteria
lt(Object o)
使用$lt
运算符创建一个标准 -
Criteria
lte(Object o)
使用$lte
运算符创建一个标准 -
Criteria
mod(Number value, Number remainder)
使用$mod
运算符创建一个标准 -
Criteria
ne(Object o)
使用$ne
运算符创建一个标准 -
Criteria
nin(Object… o)
使用$nin
运算符创建一个标准 -
Criteria
norOperator(Criteria… criteria)
对所有提供的标准使用$nor
运算符创建一个也不查询 -
Criteria
norOperator(Collection<Criteria> criteria)
对所有提供的标准使用$nor
运算符创建一个也不查询 -
Criteria
not()
创建一个使用$not
元运算符的标准,该运算符会影响直接跟随的子句 -
Criteria
orOperator(Criteria… criteria)
对所有提供的标准使用$or
运算符创建一个或者查询 -
Criteria
orOperator(Collection<Criteria> criteria)
对所有提供的标准使用$or
运算符创建一个或者查询 -
Criteria
regex(String re)
使用$regex
创建一个标准 -
Criteria
sampleRate(double sampleRate)
使用$sampleRate
运算符创建一个标准 -
Criteria
size(int s)
使用$size
运算符创建一个标准 -
Criteria
type(int t)
使用$type
运算符创建一个标准 -
Criteria
matchingDocumentStructure(MongoJsonSchema schema)
为 JSON schema criteria 创建一个使用$jsonSchema
运算符的标准。$jsonSchema
仅可应用于查询的最顶级,而不能特定于某个属性。要匹配嵌套字段,请使用模式的properties
属性。 -
Criteria
bits() 是通往 MongoDB bitwise query operators 的门户,如$bitsAllClear
。
Criteria
类还为地理空间查询提供了以下方法。
-
Criteria
within(Circle circle)
使用$geoWithin $center
算符创建一个地理空间准则。 -
Criteria
within(Box box)
使用$geoWithin $box
操作创建一个地理空间准则。 -
Criteria
withinSphere(Circle circle)
使用$geoWithin $center
算符创建一个地理空间准则。 -
Criteria
near(Point point)
使用$near
操作创建一个地理空间准则。 -
Criteria
nearSphere(Point point)
使用$nearSphere$center
操作创建一个地理空间准则。仅适用于 MongoDB 1.7 及更高版本。 -
Criteria
minDistance(double minDistance)
使用$minDistance
操作创建一个地理空间准则,以与 $near 结合使用。 -
Criteria
maxDistance(double maxDistance)
使用$maxDistance
操作创建一个地理空间准则,以与 $near 结合使用。
Query
类有一些其他方法,允许选择某些字段以及限制和排序结果。
-
Query
addCriteria(Criteria criteria)
用于向查询添加其他准则 -
Field
fields()
用于定义要包含在查询结果中的字段 -
Query
limit(int limit)
用于将返回结果的大小限制在所给的限制之内(用于分页) -
Query
skip(int skip)
用于跳过结果中所给数量的文档(用于分页) -
Query
with(Sort sort)
用于提供结果的排序定义 -
Query
with(ScrollPosition position)
用于提供一个滚动位置(基于偏移或数据集分页)来启动或恢复一个Scroll
模板 API 允许直接使用结果投影,这些投影使你能够针对给定的域类型映射查询,同时将操作结果投影到另一个域类型,如下所述。
class
template.query(SWCharacter.class)
.as(Jedi.class)
有关结果投影的更多信息,请参考文档的 Projections 部分。
Selecting fields
MongoDB 支持查询返回的 projecting fields。基于字段名称,投影可以包括和排除字段(除非明确排除,否则始终包括 _id
字段)。
public class Person {
@Id String id;
String firstname;
@Field("last_name")
String lastname;
Address address;
}
query.fields().include("lastname"); 1
query.fields().exclude("id").include("lastname") 2
query.fields().include("address") 3
query.fields().include("address.city") 4
1 | 结果将通过 { "last_name" : 1 } 包含 _id 和 last_name 。 |
2 | 结果将仅通过 { "_id" : 0, "last_name" : 1 } 包含 last_name 。 |
3 | 结果将通过 { "address" : 1 } 包含 _id 和完整的 address 对象。 |
4 | 结果将通过 { "address.city" : 1 } 包含 _id 和仅包含 city 字段的 address 对象。 |
从 MongoDB 4.4 开始,你可以对字段投影使用聚合表达式,如下所示:
query.fields()
.project(MongoExpression.create("'$toUpper' : '$last_name'")) 1
.as("last_name"); 2
query.fields()
.project(StringOperators.valueOf("lastname").toUpper()) 3
.as("last_name");
query.fields()
.project(AggregationSpELExpression.expressionOf("toUpper(lastname)")) 4
.as("last_name");
1 | 使用原生表达式。所用的字段名称必须引用数据库文档中的字段名称。 |
2 | 将字段名称分配给表达式结果所映射到的字段。产生的字段名称不映射到域模型。 |
3 | 使用 AggregationExpression 。除了原生 MongoExpression 之外,字段名称映射到域模型中所用的字段名称。 |
4 | 使用 SpEL 以及 AggregationExpression 来调用表达式函数。字段名称映射到域模型中所用的字段名称。 |
`@Query(fields="…")`允许在 `Repository`级别使用表达式字段投影,如 MongoDB JSON-based Query Methods and Field Restriction中所述。
Additional Query Options
MongoDB 提供了多种方法向查询应用元信息,例如注释或批大小。直接使用 Query
API 时,有几种方法可以实现这些选项。
Hints
索引提示可以用两种方式应用:使用索引名称或其字段定义。
template.query(Person.class)
.matching(query("...").withHint("index-to-use"));
template.query(Person.class)
.matching(query("...").withHint("{ firstname : 1 }"));
Cursor Batch Size
游标批大小定义每个响应批中要返回的文档数。
Query query = query(where("firstname").is("luke"))
.cursorBatchSize(100)
Collations
对集合操作使用排序涉及在查询或操作选项中指定 Collation
实例,如下例所示:
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);
Query Distinct Values
MongoDB 提供了一个操作,通过使用查询从结果文档中获取单个字段的不同值。结果值不必具有相同的数据类型,该特性也不限于简单类型。出于转换和类型的考虑,实际结果类型在检索中很重要。以下示例展示了如何查询不同值:
template.query(Person.class) 1
.distinct("lastname") 2
.all(); 3
1 | Query the Person collection. |
2 | 选择 lastname 字段的唯一值。字段名称根据域类型属性声明进行映射,并考虑潜在的 @Field 注释。 |
3 | 检索所有唯一值,作为 Object 的 List (由于未指定显式结果类型)。 |
将不同值检索到 Object
的 Collection
中是最灵活的方式,因为它尝试确定域类型的属性值并将结果转换为所需的类型或映射 Document
结构。
有时,当所需字段的所有值固定为某个类型时,直接获取类型正确的 Collection
会更方便,如下例所示:
template.query(Person.class) 1
.distinct("lastname") 2
.as(String.class) 3
.all(); 4
1 | 查询 Person 的集合。 |
2 | 选择 lastname 字段的唯一值。字段名称根据域类型属性声明进行映射,并考虑潜在的 @Field 注释。 |
3 | 检索到的值将转换为所需的 target 类型 - 在本例中为 String 。如果存储的字段包含一个文档,也可以将这些值映射到一个更复杂的类型。 |
4 | 以 add 的 MyExtension 形式检索所有不同值。如果类型无法转换成所需的类型,则此方法将抛出 3 。 |
+= 地理空间查询
MongoDB 通过使用`$near`、$within
、geoWithin
和 $nearSphere
等运算符支持地理空间查询。Criteria
类中有专门针对地理空间查询的方法。还有几个形状类(Box
、Circle
和 Point
),它们与地理空间相关的 Criteria
方法结合使用。
在 MongoDB 事务中使用 GeoSpatial 查询时需要小心,请参阅Special behavior inside transactions。 |
要了解如何执行 GeoSpatial 查询,请考虑以下 Venue
类(取自集成测试,并依赖于丰富的 MappingMongoConverter
):
@Document(collection="newyork")
public class Venue {
@Id
private String id;
private String name;
private double[] location;
@PersistenceConstructor
Venue(String name, double[] location) {
super();
this.name = name;
this.location = location;
}
public Venue(String name, double x, double y) {
super();
this.name = name;
this.location = new double[] { x, y };
}
public String getName() {
return name;
}
public double[] getLocation() {
return location;
}
@Override
public String toString() {
return "Venue [id=" + id + ", name=" + name + ", location="
+ Arrays.toString(location) + "]";
}
}
要查找 Circle
内的位置,可以使用以下查询:
Circle circle = new Circle(-73.99171, 40.738868, 0.01);
List<Venue> venues =
template.find(new Query(Criteria.where("location").within(circle)), Venue.class);
要使用球面坐标在 Circle
内查找场所,可以使用以下查询:
Circle circle = new Circle(-73.99171, 40.738868, 0.003712240453784);
List<Venue> venues =
template.find(new Query(Criteria.where("location").withinSphere(circle)), Venue.class);
要查找 Box
内的场所,可以使用以下查询:
//lower-left then upper-right
Box box = new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404));
List<Venue> venues =
template.find(new Query(Criteria.where("location").within(box)), Venue.class);
要查找 Point
附近的场所,可以使用以下查询:
Point point = new Point(-73.99171, 40.738868);
List<Venue> venues =
template.find(new Query(Criteria.where("location").near(point).maxDistance(0.01)), Venue.class);
Point point = new Point(-73.99171, 40.738868);
List<Venue> venues =
template.find(new Query(Criteria.where("location").near(point).minDistance(0.01).maxDistance(100)), Venue.class);
要使用球形坐标查找 Point
附近的场所,可以使用以下查询:
Point point = new Point(-73.99171, 40.738868);
List<Venue> venues =
template.find(new Query(
Criteria.where("location").nearSphere(point).maxDistance(0.003712240453784)),
Venue.class);
Geo-near Queries
Changed in 2.2! MongoDB 4.2 移除了对 geoNear
命令的支持,该命令之前用于运行 NearQuery
。
Spring Data MongoDB 2.2 MongoOperations#geoNear
使用 $geoNear
aggregation 而非 geoNear
命令来运行 NearQuery
。
以前在包装类型中返回的计算距离(使用 geoNear 命令时的 dis
)现在已嵌入到结果文档中。如果给定的域类型已经包含了具有该名称的属性,则计算出的距离将命名为 calculated-distance
,并附加一个潜在的随机后缀。
目标类型可能包含一个以返回距离命名的属性,以(附加)将其直接读回到域类型中,如下所示。
GeoResults<VenueWithDistanceField> = template.query(Venue.class) 1
.as(VenueWithDistanceField.class) 2
.near(NearQuery.near(new GeoJsonPoint(-73.99, 40.73), KILOMETERS))
.all();
1 | 用于识别目标集合和潜在查询映射的域类型。 |
2 | 目标类型,包含一个 add 类型为 MyExtension 的字段。 |
MongoDB 支持同时查询数据库中的地理位置并计算到给定原点距离的功能。通过 geon-near 查询,你可以表达诸如“查找周围 10 英里内的所有餐馆”之类的查询。为了让你做到这一点,MongoOperations
提供了 geoNear(…)
方法,该方法以 NearQuery
作为参数(以及已经熟悉的实体类型和集合),如下例所示:
Point location = new Point(-73.99171, 40.738868);
NearQuery query = NearQuery.near(location).maxDistance(new Distance(10, Metrics.MILES));
GeoResults<Restaurant> = operations.geoNear(query, Restaurant.class);
我们使用 NearQuery
构建器 API 设置一个查询,以返回给定 Point
周围所有距离不超过 10 英里的 Restaurant
实例。这里使用的 Metrics
枚举实际上实现了某个接口,以便还可以将其他指标纳入距离中。Metric
由某个乘数支持,以将给定指标的距离值转换为本机距离。此处所示的样本会将 10 视为英里。使用其中一个内置指标(英里和公里)时,会自动触发将球面标志设置为该查询。如果您要避免这种情况,请将纯 double
值传递到 maxDistance(…)
。有关更多信息,请参阅 JavaDoc 中的 NearQuery
和 Distance
。
geo-near 操作返回一个封装 GeoResult
实例的 GeoResults
包装对象。包装 GeoResults
允许访问所有结果的平均距离。一个 GeoResult
对象承载找到的实体及其到原点的距离。
GeoJSON Support
MongoDB 为地理空间数据支持 GeoJSON 和简单的(旧版)坐标对。这些格式都可用于存储和查询数据。请参阅 MongoDB manual on GeoJSON support 以了解要求和限制。
GeoJSON Types in Domain Classes
在域类中使用 GeoJSON 类型很简单。org.springframework.data.mongodb.core.geo
包含 GeoJsonPoint
、GeoJsonPolygon
等类型。这些类型扩展了现有的 org.springframework.data.geo
类型。以下示例使用 GeoJsonPoint
:
public class Store {
String id;
/**
* { "type" : "Point", "coordinates" : [ x, y ] }
*/
GeoJsonPoint location;
}
如果 GeoJSON 对象的 |
GeoJSON Types in Repository Query Methods
使用 GeoJSON 类型作为存储库查询参数会强制在创建查询时使用 $geometry
运算符,如下例所示:
public interface StoreRepository extends CrudRepository<Store, String> {
List<Store> findByLocationWithin(Polygon polygon); 1
}
/*
* {
* "location": {
* "$geoWithin": {
* "$geometry": {
* "type": "Polygon",
* "coordinates": [
* [
* [-73.992514,40.758934],
* [-73.961138,40.760348],
* [-73.991658,40.730006],
* [-73.992514,40.758934]
* ]
* ]
* }
* }
* }
* }
*/
repo.findByLocationWithin( 2
new GeoJsonPolygon(
new Point(-73.992514, 40.758934),
new Point(-73.961138, 40.760348),
new Point(-73.991658, 40.730006),
new Point(-73.992514, 40.758934))); 3
/*
* {
* "location" : {
* "$geoWithin" : {
* "$polygon" : [ [-73.992514,40.758934] , [-73.961138,40.760348] , [-73.991658,40.730006] ]
* }
* }
* }
*/
repo.findByLocationWithin( 4
new Polygon(
new Point(-73.992514, 40.758934),
new Point(-73.961138, 40.760348),
new Point(-73.991658, 40.730006)));
1 | 使用公共类型的仓库方法定义让其可以同时使用 GeoJSON 和传统格式来调用。 |
2 | 使用 GeoJSON 类型来使用 add 运算符。 |
3 | 请注意,GeoJSON 多边形需要定义闭合环。 |
4 | 使用传统格式 add 运算符。 |
Metrics and Distance calculation
然后,MongoDB $geoNear
运算符允许使用 GeoJSON 点或传统坐标对。
NearQuery.near(new Point(-73.99171, 40.738868))
{
"$geoNear": {
//...
"near": [-73.99171, 40.738868]
}
}
NearQuery.near(new GeoJsonPoint(-73.99171, 40.738868))
{
"$geoNear": {
//...
"near": { "type": "Point", "coordinates": [-73.99171, 40.738868] }
}
}
尽管语法不同,但无论集合中目标 Document 使用什么格式,服务器都可以接受这两种格式。
距离计算存在巨大差异。使用旧格式在类球体的_地球_上进行操作,而 GeoJSON 格式使用 Meters。
为避免严重的头疼,确保将“Metric”设置为所需的测量单位,这可确保正确计算距离。
换句话说:
假设您有 5 个类似于以下的 Document:
{
"_id" : ObjectId("5c10f3735d38908db52796a5"),
"name" : "Penn Station",
"location" : { "type" : "Point", "coordinates" : [ -73.99408, 40.75057 ] }
}
{
"_id" : ObjectId("5c10f3735d38908db52796a6"),
"name" : "10gen Office",
"location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
}
{
"_id" : ObjectId("5c10f3735d38908db52796a9"),
"name" : "City Bakery ",
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
}
{
"_id" : ObjectId("5c10f3735d38908db52796aa"),
"name" : "Splash Bar",
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
}
{
"_id" : ObjectId("5c10f3735d38908db52796ab"),
"name" : "Momofuku Milk Bar",
"location" : { "type" : "Point", "coordinates" : [ -73.985839, 40.731698 ] }
}
使用 GeoJSON 从 [-73.99171, 40.738868]
提取 400 米半径内的所有文档看起来如下所示:
{
"$geoNear": {
"maxDistance": 400, 1
"num": 10,
"near": { type: "Point", coordinates: [-73.99171, 40.738868] },
"spherical":true, 2
"key": "location",
"distanceField": "distance"
}
}
返回以下 3 个 Document:
{
"_id" : ObjectId("5c10f3735d38908db52796a6"),
"name" : "10gen Office",
"location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
"distance" : 0.0 3
}
{
"_id" : ObjectId("5c10f3735d38908db52796a9"),
"name" : "City Bakery ",
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
"distance" : 69.3582262492474 3
}
{
"_id" : ObjectId("5c10f3735d38908db52796aa"),
"name" : "Splash Bar",
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
"distance" : 69.3582262492474 3
}
1 | 从中心点在 add 中的最大距离。 |
2 | GeoJSON 始终在球面上进行操作。 |
3 | 从中心点距离 add 。 |
现在,当使用旧的坐标对时,正如之前讨论过的,操作在 Radians 上进行。因此,在构造 $geoNear
命令时,我们使用了 Metrics#KILOMETERS
。Metric
确保正确设置距离倍率。
{
"$geoNear": {
"maxDistance": 0.0000627142377, 1
"distanceMultiplier": 6378.137, 2
"num": 10,
"near": [-73.99171, 40.738868],
"spherical":true, 3
"key": "location",
"distanceField": "distance"
}
}
返回 3 个 Document,与 GeoJSON 变体相同:
{
"_id" : ObjectId("5c10f3735d38908db52796a6"),
"name" : "10gen Office",
"location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
"distance" : 0.0 4
}
{
"_id" : ObjectId("5c10f3735d38908db52796a9"),
"name" : "City Bakery ",
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
"distance" : 0.0693586286032982 4
}
{
"_id" : ObjectId("5c10f3735d38908db52796aa"),
"name" : "Splash Bar",
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
"distance" : 0.0693586286032982 4
}
1 | 从中心点在 add 中的最大距离。 |
2 | 距离乘数因此我们得到 Kilometers 作为生成距离。 |
3 | 确保我们在 2d_sphere 索引上进行操作。 |
4 | 从中心点计算到 Kilometers 的距离 - 将其乘以 1000 以匹配 GeoJSON 变体的 Meters。 |
Full-text Search
从 MongoDB 版本 2.6 开始,可以使用 `$text`算子运行全文查询。特定于全文查询的方法和操作在 `TextQuery`和 `TextCriteria`中可用。在进行全文搜索时,请参阅 MongoDB reference以了解其行为和限制。
在実際に使用全文搜索之前,必须正确设置搜索索引。有关如何创建索引结构的更多详细信息,请参见 Text Index。以下示例展示了如何设置全文搜索:
db.foo.createIndex(
{
title : "text",
content : "text"
},
{
weights : {
title : 3
}
}
)
可以将搜索 coffee cake
的查询定义并运行如下:
Query query = TextQuery
.queryText(new TextCriteria().matchingAny("coffee", "cake"));
List<Document> page = template.find(query, Document.class);
要按照 weights
的相关性对结果进行排序,请使用 TextQuery.sortByScore
。
Query query = TextQuery
.queryText(new TextCriteria().matchingAny("coffee", "cake"))
.sortByScore() 1
.includeScore(); 2
List<Document> page = template.find(query, Document.class);
1 | 使用评分属性按相关性对结果进行排序,这将触发 .sort({'score': {'$meta': 'textScore'}}) 。 |
2 | 使用 TextQuery.includeScore() 在生成的 Document 中包含计算的相关性。 |
您可以通过在术语前加上 -
或使用 notMatching
来排除搜索术语,如下例所示(请注意,这两行具有相同的效果,因此是多余的):
// search for 'coffee' and not 'cake'
TextQuery.queryText(new TextCriteria().matching("coffee").matching("-cake"));
TextQuery.queryText(new TextCriteria().matching("coffee").notMatching("cake"));
TextCriteria.matching
将提供的术语按原样接受。因此,您可以通过将它们放在双引号之间(例如 \"coffee cake\")
或使用 TextCriteria.phrase.
来定义短语。以下示例显示了定义短语的两种方法:
// search for phrase 'coffee cake'
TextQuery.queryText(new TextCriteria().matching("\"coffee cake\""));
TextQuery.queryText(new TextCriteria().phrase("coffee cake"));
您可以使用 TextCriteria
上的对应方法设置 $caseSensitive
和 $diacriticSensitive
的标志。请注意,这两个可选标志已在 MongoDB 3.2 中引入,并且必须明确设置才能包含在查询中。
Query by Example
Query by Example可以在模板 API 级别运行示例查询上使用。
以下代码段显示了如何按示例进行查询:
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);
默认情况下,Example
是严格类型化的。这意味着映射的查询具有包含的类型匹配,将其限制为探查可分配的类型。例如,在坚持使用默认类型键 (_class
) 的情况下,查询具有以下类型的限制:(_class : { $in : [ com.acme.Person] }
)。
通过使用 UntypedExampleMatcher
,可以绕过默认行为并跳过类型限制。因此,只要字段名称匹配,几乎任何域类型都可以用作创建引用的探测,如下例所示:
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);
当在 |
如果要在单个集合中存储不同实体或选择不编写类型提示,那么 |
Spring Data MongoDB 为不同的匹配选项提供了支持:
StringMatcher
optionsMatching | Logical result |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Query a collection for matching JSON Schema
你可以使用模式查询文档集合,以便找到与 JSON 模式定义的给定结构匹配的文档,如下例所示:
$jsonSchema
MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();
template.find(query(matchingDocumentStructure(schema)), Person.class);
请参阅 JSON Schema 部分以了解有关 Spring Data MongoDB 中架构支持的更多信息。