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
实例,如下例所示:
You can use the Query
and Criteria
classes to express your queries.
They have method names that mirror the native MongoDB operator names, such as lt
, lte
, is
, and others.
The Query
and Criteria
classes follow a fluent API style so that you can chain together multiple method criteria and queries while having easy-to-understand code.
To improve readability, static imports let you avoid using the 'new' keyword for creating Query
and Criteria
instances.
You can also use BasicQuery
to create Query
instances from plain JSON Strings, as shown in the following example:
.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
对象,并且每个人都有一个嵌入了余额的帐户文档,那么我们现在可以使用以下代码运行查询:
Earlier, we saw how to retrieve a single document by using the findOne
and findById
methods on MongoTemplate
.
These methods return a single domain object right way or using a reactive API a Mono
emitting a single element.
We can also query for a collection of documents to be returned as a list of domain objects.
Assuming that we have a number of Person
objects with name and age stored as documents in a collection and that each person has an embedded account document with a balance, we can now run a query using the following code:
-
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
使用静态导入以使查询更具可读性。
All find methods take a Query
object as a parameter.
This object defines the criteria and options used to perform the query.
The criteria are specified by using a Criteria
object that has a static factory method named where
to instantiate a new Criteria
object.
We recommend using static imports for org.springframework.data.mongodb.core.query.Criteria.where
and Query.query
to make the query more readable.
查询应该返回满足指定条件的 Person
对象的 List
或 Flux
。本节的其余部分列出了 Criteria
和 Query
类的对应于 MongoDB 中提供的运算符的方法。大多数方法返回 Criteria
对象,以便为 API 提供流畅的样式。
The query should return a List
or Flux
of Person
objects that meet the specified criteria.
The rest of this section lists the methods of the Criteria
and Query
classes that correspond to the operators provided in MongoDB.
Most methods return the Criteria
object, to provide a fluent style for the API.
Criteria
类提供以下方法,它们都对应 MongoDB 中的操作符:
The Criteria
class provides the following methods, all of which correspond to operators in MongoDB:
-
Criteria
all(Object o)
Creates a criterion using the$all
operator -
Criteria
and(String key)
Adds a chainedCriteria
with the specifiedkey
to the currentCriteria
and returns the newly created one -
Criteria
andOperator(Criteria… criteria)
Creates an and query using the$and
operator for all of the provided criteria (requires MongoDB 2.0 or later) -
Criteria
andOperator(Collection<Criteria> criteria)
Creates an and query using the$and
operator for all of the provided criteria (requires MongoDB 2.0 or later) -
Criteria
elemMatch(Criteria c)
Creates a criterion using the$elemMatch
operator -
Criteria
exists(boolean b)
Creates a criterion using the$exists
operator -
Criteria
gt(Object o)
Creates a criterion using the$gt
operator -
Criteria
gte(Object o)
Creates a criterion using the$gte
operator -
Criteria
in(Object… o)
Creates a criterion using the$in
operator for a varargs argument. -
Criteria
in(Collection<?> collection)
Creates a criterion using the$in
operator using a collection -
Criteria
is(Object o)
Creates a criterion using field matching ({ key:value }
). If the specified value is a document, the order of the fields and exact equality in the document matters. -
Criteria
lt(Object o)
Creates a criterion using the$lt
operator -
Criteria
lte(Object o)
Creates a criterion using the$lte
operator -
Criteria
mod(Number value, Number remainder)
Creates a criterion using the$mod
operator -
Criteria
ne(Object o)
Creates a criterion using the$ne
operator -
Criteria
nin(Object… o)
Creates a criterion using the$nin
operator -
Criteria
norOperator(Criteria… criteria)
Creates an nor query using the$nor
operator for all of the provided criteria -
Criteria
norOperator(Collection<Criteria> criteria)
Creates an nor query using the$nor
operator for all of the provided criteria -
Criteria
not()
Creates a criterion using the$not
meta operator which affects the clause directly following -
Criteria
orOperator(Criteria… criteria)
Creates an or query using the$or
operator for all of the provided criteria -
Criteria
orOperator(Collection<Criteria> criteria)
Creates an or query using the$or
operator for all of the provided criteria -
Criteria
regex(String re)
Creates a criterion using a$regex
-
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 JSON schema criteria.$jsonSchema
can only be applied on the top level of a query and not property specific. Use theproperties
attribute of the schema to match against nested fields. -
Criteria
bits() is the gateway to MongoDB bitwise query operators like$bitsAllClear
.
Criteria
类还为地理空间查询提供了以下方法。
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. -
Criteria
withinSphere(Circle circle)
Creates a geospatial criterion using$geoWithin $center
operators. -
Criteria
near(Point point)
Creates a geospatial criterion using a$near
operation -
Criteria
nearSphere(Point point)
Creates a geospatial criterion using$nearSphere$center
operations. This is only available for MongoDB 1.7 and higher. -
Criteria
minDistance(double minDistance)
Creates a geospatial criterion using the$minDistance
operation, for use with $near. -
Criteria
maxDistance(double maxDistance)
Creates a geospatial criterion using the$maxDistance
operation, for use with $near.
Query
类有一些其他方法,允许选择某些字段以及限制和排序结果。
The Query
class has some additional methods that allow to select certain fields as well as to limit and sort the result.
-
Query
addCriteria(Criteria criteria)
used to add additional criteria to the query -
Field
fields()
used to define fields to be included in the query results -
Query
limit(int limit)
used to limit the size of the returned results to the provided limit (used for paging) -
Query
skip(int skip)
used to skip the provided number of documents in the results (used for paging) -
Query
with(Sort sort)
used to provide sort definition for the results -
Query
with(ScrollPosition position)
used to provide a scroll position (Offset- or Keyset-based pagination) to start or resume aScroll
模板 API 允许直接使用结果投影,这些投影使你能够针对给定的域类型映射查询,同时将操作结果投影到另一个域类型,如下所述。
The template API allows direct usage of result projections that enable you to map queries against a given domain type while projecting the operation result onto another one as outlined below.
class
template.query(SWCharacter.class)
.as(Jedi.class)
有关结果投影的更多信息,请参考文档的 Projections 部分。
For more information on result projections please refer to the Projections section of the documentation.
Selecting fields
MongoDB 支持查询返回的 projecting fields。基于字段名称,投影可以包括和排除字段(除非明确排除,否则始终包括 _id
字段)。
MongoDB supports projecting fields returned by a query.
A projection can include and exclude fields (the _id
field is always included unless explicitly excluded) based on their name.
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 | Result will contain both _id and last_name via { "last_name" : 1 } . |
2 | Result will only contain the last_name via { "_id" : 0, "last_name" : 1 } . |
3 | Result will contain the _id and entire address object via { "address" : 1 } . |
4 | Result will contain the _id and and address object that only contains the city field via { "address.city" : 1 } . |
从 MongoDB 4.4 开始,你可以对字段投影使用聚合表达式,如下所示:
Starting with MongoDB 4.4 you can use aggregation expressions for field projections as shown below:
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 | Use a native expression. The used field name must refer to field names within the database document. |
2 | Assign the field name to which the expression result is projected. The resulting field name is not mapped against the domain model. |
3 | Use an AggregationExpression . Other than native MongoExpression , field names are mapped to the ones used in the domain model. |
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="…")`允许在 `Repository`级别使用表达式字段投影,如 MongoDB JSON-based Query Methods and Field Restriction中所述。
@Query(fields="…")
allows usage of expression field projections at Repository
level as described in MongoDB JSON-based Query Methods and Field Restriction.
Additional Query Options
MongoDB 提供了多种方法向查询应用元信息,例如注释或批大小。直接使用 Query
API 时,有几种方法可以实现这些选项。
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.
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.
Query query = query(where("firstname").is("luke"))
.cursorBatchSize(100)
Collations
对集合操作使用排序涉及在查询或操作选项中指定 Collation
实例,如下例所示:
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:
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
要使用的 ReadPreference
可以直接设置在要运行的 Query
对象上,如下所述。
The ReadPreference
to use can be set directly on the Query
object to be run as outlined below.
template.find(Person.class)
.matching(query(where(...)).withReadPreference(ReadPreference.secondary()))
.all();
在 |
The preference set on the |
Query Distinct Values
MongoDB 提供了一个操作,通过使用查询从结果文档中获取单个字段的不同值。结果值不必具有相同的数据类型,该特性也不限于简单类型。出于转换和类型的考虑,实际结果类型在检索中很重要。以下示例展示了如何查询不同值:
MongoDB provides an operation to obtain distinct values for a single field by using a query from the resulting documents. Resulting values are not required to have the same data type, nor is the feature limited to simple types. For retrieval, the actual result type does matter for the sake of conversion and typing. The following example shows how to query for distinct values:
template.query(Person.class) 1
.distinct("lastname") 2
.all(); 3
1 | Query the Person collection. |
2 | Select distinct values of the lastname field. The field name is mapped according to the domain types property declaration, taking potential @Field annotations into account. |
3 | Retrieve all distinct values as a List of Object (due to no explicit result type being specified). |
将不同值检索到 Object
的 Collection
中是最灵活的方式,因为它尝试确定域类型的属性值并将结果转换为所需的类型或映射 Document
结构。
Retrieving distinct values into a Collection
of Object
is the most flexible way, as it tries to determine the property value of the domain type and convert results to the desired type or mapping Document
structures.
有时,当所需字段的所有值固定为某个类型时,直接获取类型正确的 Collection
会更方便,如下例所示:
Sometimes, when all values of the desired field are fixed to a certain type, it is more convenient to directly obtain a correctly typed Collection
, as shown in the following example:
template.query(Person.class) 1
.distinct("lastname") 2
.as(String.class) 3
.all(); 4
1 | Query the collection of Person . |
2 | Select distinct values of the lastname field. The fieldname is mapped according to the domain types property declaration, taking potential @Field annotations into account. |
3 | Retrieved values are converted into the desired target type — in this case, String . It is also possible to map the values to a more complex type if the stored field contains a document. |
4 | Retrieve all distinct values as a List of String . If the type cannot be converted into the desired target type, this method throws a DataAccessException . |
+= 地理空间查询
+= GeoSpatial Queries
MongoDB 通过使用`$near`、$within
、geoWithin
和 $nearSphere
等运算符支持地理空间查询。Criteria
类中有专门针对地理空间查询的方法。还有几个形状类(Box
、Circle
和 Point
),它们与地理空间相关的 Criteria
方法结合使用。
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.
在 MongoDB 事务中使用 GeoSpatial 查询时需要小心,请参阅Special behavior inside transactions。 |
Using GeoSpatial queries requires attention when used within MongoDB transactions, see Special behavior inside transactions. |
要了解如何执行 GeoSpatial 查询,请考虑以下 Venue
类(取自集成测试,并依赖于丰富的 MappingMongoConverter
):
To understand how to perform GeoSpatial queries, consider the following Venue
class (taken from the integration tests and relying on the rich 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
内的位置,可以使用以下查询:
To find locations within a Circle
, you can use the following query:
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
内查找场所,可以使用以下查询:
To find venues within a Circle
using spherical coordinates, you can use the following query:
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
内的场所,可以使用以下查询:
To find venues within a Box
, you can use the following query:
//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
附近的场所,可以使用以下查询:
To find venues near a Point
, you can use the following queries:
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
附近的场所,可以使用以下查询:
To find venues near a Point
using spherical coordinates, you can use the following query:
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
。
Changed in 2.2!
MongoDB 4.2 removed support for the
geoNear
command which had been previously used to run the NearQuery
.
Spring Data MongoDB 2.2 MongoOperations#geoNear
使用 $geoNear
aggregation 而非 geoNear
命令来运行 NearQuery
。
Spring Data MongoDB 2.2 MongoOperations#geoNear
uses the $geoNear
aggregation
instead of the geoNear
command to run a NearQuery
.
以前在包装类型中返回的计算距离(使用 geoNear 命令时的 dis
)现在已嵌入到结果文档中。如果给定的域类型已经包含了具有该名称的属性,则计算出的距离将命名为 calculated-distance
,并附加一个潜在的随机后缀。
The calculated distance (the dis
when using a geoNear command) previously returned within a wrapper type now is embedded
into the resulting document.
If the given domain type already contains a property with that name, the calculated distance
is named calculated-distance
with a potentially random postfix.
目标类型可能包含一个以返回距离命名的属性,以(附加)将其直接读回到域类型中,如下所示。
Target types may contain a property named after the returned distance to (additionally) read it back directly into the domain type as shown below.
GeoResults<VenueWithDistanceField> = template.query(Venue.class) 1
.as(VenueWithDistanceField.class) 2
.near(NearQuery.near(new GeoJsonPoint(-73.99, 40.73), KILOMETERS))
.all();
1 | Domain type used to identify the target collection and potential query mapping. |
2 | Target type containing a dis field of type Number . |
MongoDB 支持同时查询数据库中的地理位置并计算到给定原点距离的功能。通过 geon-near 查询,你可以表达诸如“查找周围 10 英里内的所有餐馆”之类的查询。为了让你做到这一点,MongoOperations
提供了 geoNear(…)
方法,该方法以 NearQuery
作为参数(以及已经熟悉的实体类型和集合),如下例所示:
MongoDB supports querying the database for geo locations and calculating the distance from a given origin at the same time. With geo-near queries, you can express queries such as "find all restaurants in the surrounding 10 miles". To let you do so, MongoOperations
provides geoNear(…)
methods that take a NearQuery
as an argument (as well as the already familiar entity type and collection), as shown in the following example:
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
。
We use the NearQuery
builder API to set up a query to return all Restaurant
instances surrounding the given Point
out to 10 miles.
The Metrics
enum used here actually implements an interface so that other metrics could be plugged into a distance as well.
A Metric
is backed by a multiplier to transform the distance value of the given metric into native distances.
The sample shown here would consider the 10 to be miles. Using one of the built-in metrics (miles and kilometers) automatically triggers the spherical flag to be set on the query.
If you want to avoid that, pass plain double
values into maxDistance(…)
.
For more information, see the JavaDoc of NearQuery
and Distance
.
geo-near 操作返回一个封装 GeoResult
实例的 GeoResults
包装对象。包装 GeoResults
允许访问所有结果的平均距离。一个 GeoResult
对象承载找到的实体及其到原点的距离。
The geo-near operations return a GeoResults
wrapper object that encapsulates GeoResult
instances.
Wrapping GeoResults
allows accessing the average distance of all results.
A single GeoResult
object carries the entity found plus its distance from the origin.
GeoJSON Support
MongoDB 为地理空间数据支持 GeoJSON 和简单的(旧版)坐标对。这些格式都可用于存储和查询数据。请参阅 MongoDB manual on GeoJSON support 以了解要求和限制。
MongoDB supports GeoJSON and simple (legacy) coordinate pairs for geospatial data. Those formats can both be used for storing as well as querying data. See the MongoDB manual on GeoJSON support to learn about requirements and restrictions.
GeoJSON Types in Domain Classes
在域类中使用 GeoJSON 类型很简单。org.springframework.data.mongodb.core.geo
包含 GeoJsonPoint
、GeoJsonPolygon
等类型。这些类型扩展了现有的 org.springframework.data.geo
类型。以下示例使用 GeoJsonPoint
:
Usage of GeoJSON types in domain classes is straightforward. The org.springframework.data.mongodb.core.geo
package contains types such as GeoJsonPoint
, GeoJsonPolygon
, and others. These types are extend the existing org.springframework.data.geo
types. The following example uses a GeoJsonPoint
:
public class Store {
String id;
/**
* { "type" : "Point", "coordinates" : [ x, y ] }
*/
GeoJsonPoint location;
}
如果 GeoJSON 对象的 If the |
GeoJSON Types in Repository Query Methods
使用 GeoJSON 类型作为存储库查询参数会强制在创建查询时使用 $geometry
运算符,如下例所示:
Using GeoJSON types as repository query parameters forces usage of the $geometry
operator when creating the query, as the following example shows:
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 | Repository method definition using the commons type allows calling it with both the GeoJSON and the legacy format. |
2 | Use GeoJSON type to make use of $geometry operator. |
3 | Note that GeoJSON polygons need to define a closed ring. |
4 | Use the legacy format $polygon operator. |
Metrics and Distance calculation
然后,MongoDB $geoNear
运算符允许使用 GeoJSON 点或传统坐标对。
Then MongoDB $geoNear
operator allows usage of a GeoJSON Point or legacy coordinate pairs.
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 使用什么格式,服务器都可以接受这两种格式。
Though syntactically different the server is fine accepting both no matter what format the target Document within the collection is using.
距离计算存在巨大差异。使用旧格式在类球体的_地球_上进行操作,而 GeoJSON 格式使用 Meters。
There is a huge difference in the distance calculation. Using the legacy format operates upon Radians on an Earth like sphere, whereas the GeoJSON format uses Meters.
为避免严重的头疼,确保将“Metric”设置为所需的测量单位,这可确保正确计算距离。
To avoid a serious headache make sure to set the Metric
to the desired unit of measure which ensures the
distance to be calculated correctly.
换句话说:
In other words:
假设您有 5 个类似于以下的 Document:
Assume you’ve got 5 Documents like the ones below:
{
"_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 米半径内的所有文档看起来如下所示:
Fetching all Documents within a 400 Meter radius from [-73.99171, 40.738868]
would look like this using
GeoJSON:
{
"$geoNear": {
"maxDistance": 400, 1
"num": 10,
"near": { type: "Point", coordinates: [-73.99171, 40.738868] },
"spherical":true, 2
"key": "location",
"distanceField": "distance"
}
}
返回以下 3 个 Document:
Returning the following 3 Documents:
{
"_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 | Maximum distance from center point in Meters. |
2 | GeoJSON always operates upon a sphere. |
3 | Distance from center point in Meters. |
现在,当使用旧的坐标对时,正如之前讨论过的,操作在 Radians 上进行。因此,在构造 $geoNear
命令时,我们使用了 Metrics#KILOMETERS
。Metric
确保正确设置距离倍率。
Now, when using legacy coordinate pairs one operates upon Radians as discussed before. So we use Metrics#KILOMETERS
when constructing the `$geoNear
command. The Metric
makes sure the distance multiplier is set correctly.
{
"$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 变体相同:
Returning the 3 Documents just like the GeoJSON variant:
{
"_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 | Maximum distance from center point in Radians. |
2 | The distance multiplier so we get Kilometers as resulting distance. |
3 | Make sure we operate on a 2d_sphere index. |
4 | Distance from center point in Kilometers - take it times 1000 to match Meters of the GeoJSON variant. |
Full-text Search
从 MongoDB 版本 2.6 开始,可以使用 `$text`算子运行全文查询。特定于全文查询的方法和操作在 `TextQuery`和 `TextCriteria`中可用。在进行全文搜索时,请参阅 MongoDB reference以了解其行为和限制。
Since version 2.6 of MongoDB, you can run full-text queries by using the $text
operator. Methods and operations specific to full-text queries are available in TextQuery
and TextCriteria
. When doing full text search, see the MongoDB reference for its behavior and limitations.
在実際に使用全文搜索之前,必须正确设置搜索索引。有关如何创建索引结构的更多详细信息,请参见 Text Index。以下示例展示了如何设置全文搜索:
Before you can actually use full-text search, you must set up the search index correctly. See Text Index for more detail on how to create index structures. The following example shows how to set up a full-text search:
db.foo.createIndex(
{
title : "text",
content : "text"
},
{
weights : {
title : 3
}
}
)
可以将搜索 coffee cake
的查询定义并运行如下:
A query searching for coffee cake
can be defined and run as follows:
Query query = TextQuery
.queryText(new TextCriteria().matchingAny("coffee", "cake"));
List<Document> page = template.find(query, Document.class);
要按照 weights
的相关性对结果进行排序,请使用 TextQuery.sortByScore
。
To sort results by relevance according to the weights
use TextQuery.sortByScore
.
Query query = TextQuery
.queryText(new TextCriteria().matchingAny("coffee", "cake"))
.sortByScore() 1
.includeScore(); 2
List<Document> page = template.find(query, Document.class);
1 | Use the score property for sorting results by relevance which triggers .sort({'score': {'$meta': 'textScore'}}) . |
2 | Use TextQuery.includeScore() to include the calculated relevance in the resulting Document . |
您可以通过在术语前加上 -
或使用 notMatching
来排除搜索术语,如下例所示(请注意,这两行具有相同的效果,因此是多余的):
You can exclude search terms by prefixing the term with -
or by using notMatching
, as shown in the following example (note that the two lines have the same effect and are thus redundant):
// 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.
来定义短语。以下示例显示了定义短语的两种方法:
TextCriteria.matching
takes the provided term as is.
Therefore, you can define phrases by putting them between double quotation marks (for example, \"coffee cake\")
or using by TextCriteria.phrase.
The following example shows both ways of defining a 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 中引入,并且必须明确设置才能包含在查询中。
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.
Query by Example
Query by Example可以在模板 API 级别运行示例查询上使用。
Query by Example can be used on the Template API level run example queries.
以下代码段显示了如何按示例进行查询:
The following snipped shows how to query by example:
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] }
)。
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] }
).
通过使用 UntypedExampleMatcher
,可以绕过默认行为并跳过类型限制。因此,只要字段名称匹配,几乎任何域类型都可以用作创建引用的探测,如下例所示:
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:
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);
当在 When including |
如果要在单个集合中存储不同实体或选择不编写类型提示,那么
此外,请牢记使用 Also, keep in mind that using |
Spring Data MongoDB 为不同的匹配选项提供了支持:
Spring Data MongoDB provides support for different matching options:
StringMatcher
optionsMatching | Logical result |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Query a collection for matching JSON Schema
你可以使用模式查询文档集合,以便找到与 JSON 模式定义的给定结构匹配的文档,如下例所示:
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:
$jsonSchema
MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();
template.find(query(matchingDocumentStructure(schema)), Person.class);
请参阅 JSON Schema 部分以了解有关 Spring Data MongoDB 中架构支持的更多信息。
Please refer to the JSON Schema section to learn more about the schema support in Spring Data MongoDB.