当前位置: 首页 > news >正文

【Spring连载】使用Spring Data访问 MongoDB----Template API 查询Documents

【Spring连载】使用Spring Data访问 MongoDB----Template API 查询Documents

  • 一、 查询集合中的Documents
  • 二 选择字段
  • 三、 其他查询选项
    • 3.1 Hints
    • 3.2 游标批大小Cursor Batch Size
    • 3.3 Collations
    • 3.4 读取首选项Read Preference
    • 3.5 Comments
  • 四、查询Distinct值
  • 五、GeoSpatial Queries
  • 六、Geo-near 查询
  • 七、GeoJSON 支持
  • 八、域类中的GeoJSON类型
  • 九、存储库查询方法中的GeoJSON 类型
  • 十、度量和距离计算
  • 十一、全文检索
  • 十二、Query by Example
  • 十三、查询一个集合以匹配JSON Schema

你可以使用Query和Criteria类来表达查询。它们的方法名称反映了native MongoDB操作名称,如lt、lte、is和其他名称。Query和Criteria类遵循fluent API风格,因此你可以将多个方法标准和查询链接在一起,同时拥有易于理解的代码。为了提高可读性,静态导入可以避免在创建查询和条件实例时使用“new”关键字。你还可以使用BasicQuery从纯JSON字符串创建Query实例,如下例所示:
例1:从纯JSON字符串创建查询实例

BasicQuery query = new BasicQuery("{ age : { $lt : 50 }, accounts.balance : { $gt : 1000.00 }}");
List<Person> result = mongoTemplate.find(query, Person.class);

一、 查询集合中的Documents

在之前的章节,我们看到了如何在MongoTemplate上使用findOne和findById方法来检索单个文档。这些方法以正确的方式返回单个域对象,或者使用响应式(reactive )API Mono发出单个元素。我们还可以查询要作为域对象列表返回的documents集合。假设我们在一个集合中有许多具有姓名和年龄的Person对象作为documents存储,并且每个人都有一个带有余额的内嵌的帐户document,我们现在可以使用以下代码运行查询:
使用MongoTemplate查询文档

// ...List<Person> result = template.query(Person.class).matching(query(where("age").lt(50).and("accounts.balance").gt(1000.00d))).all();

所有find方法都将Query对象作为参数。此对象定义用于执行查询的条件和选项。通过使用Criteria对象来指定条件,该对象具有一个名为where的静态工厂方法来实例化新的Criteria。我们建议对org.springframework.data.mongodb.core.query.Criteria.where和Query.query使用静态导入,使查询更具可读性。
查询应该返回符合指定条件的Person对象的List或Flux。本节的剩余部分列出了与MongoDB中提供的运算符相对应的Criteria和Query类的方法。大多数方法返回Criteria对象,为API提供流畅的样式。
Criteria的方法
Criteria类提供了以下方法,所有这些方法都对应于MongoDB中的运算符:

  • Criteria all (Object o)使用$all运算符创建一个条件
  • Criteria and (String key)将具有指定key的链式Criteria添加到当前Criteria并返回新创建的Criteria
  • Criteria andOperator (Criteria…​ criteria)使用$and运算符为所有提供的条件创建and查询
  • Criteria andOperator (Collection< Criteria> criteria)使用$and运算符为所有提供的条件创建and查询
  • Criteria elemMatch (Criteria c)使用$elemMatch运算符创建条件
  • Criteria exists (boolean b)使用$exists运算符创建条件
  • Criteria gt (Object o)使用$gt运算符创建条件
  • Criteria gte (Object o)使用$gte运算符创建条件
  • Criteria in (Object…​ o) 使用$in运算符为varargs参数创建一个条件。
  • Criteria in (Collection<?> collection)使用$in运算符并使用集合创建条件
  • Criteria is (Object o)使用字段匹配({key:value})创建条件。如果指定的值是一个document,则字段的顺序和document中的完全相等性很重要。
  • 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运算符创建nor查询
  • Criteria norOperator(Collection<Criteria>Criteria)为所有提供的条件使用$nor运算符创建nor查询
  • Criteria not ()使用$not元运算符创建一个条件,该运算符直接影响后面的子句
  • Criteria orOperator (Criteria…​ criteria)为所有提供的条件使用$or运算符创建or查询
  • Criteria orOperator (Collection< Criteria> criteria)使用$或运算符为所有提供的条件创建或查询
  • Criteria regex (String re)使用$regex创建条件
  • Criteria sampleRate (double sampleRate)使用$sampleRate运算符创建条件
  • Criteria size (int s)使用$size运算符创建条件
  • Criteria type (int t)使用$type运算符创建条件
  • Criteria matchingDocumentStructure (MongoJsonSchema schema)使用 $ jsonSchema 运算符为JSON schema criteria创建一个条件。$jsonSchema只能应用于查询的顶层,而不能应用于特定属性。使用schema的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操作创建地理空间条件。
  • Criteria minDistance (double minDistance)使用 $ minDistance 操作创建地理空间条件,与$near一同使用。
  • Criteria maxDistance (double maxDistance)使用 $ maxDistance 操作创建地理空间条件,与$near一同使用。

Query类有一些附加的方法,这些方法允许选择某些字段以及对结果进行limit和排序。
Query类的方法

  • Query addCriteria (Criteria criteria),用于向查询添加其他条件
  • Field fields (),用于定义要包含在查询结果中的字段
  • Query limit (int limit)用于将返回结果的大小限制为提供的limit (用于分页)
  • Query skip(int skip)用于跳过结果中提供的documents数(用于分页)
  • Query with (Sort sort)用于为结果提供排序定义
  • Query with (ScrollPosition position)用于提供滚动(Scroll)位置(基于Offset或Keyset的分页)以开始或恢复滚动

template API允许直接使用结果投影,使你能够将查询映射到给定的域类型,同时将操作结果投影到另一个域类型,如下所述。

classtemplate.query(SWCharacter.class).as(Jedi.class)

有关结果投影的更多信息,请参阅Spring Data Projections的文档。

二 选择字段

MongoDB支持投影查询返回的字段。投影可以根据字段的名称包括和排除字段(除非明确排除,否则始终包括_id字段)。
例2:选择结果字段

public class Person {@Id String id;String firstname;@Field("last_name")String lastname;Address address;
}
query.fields().include("lastname");              --------1query.fields().exclude("id").include("lastname") --------2query.fields().include("address")                --------3query.fields().include("address.city")           --------41. 通过{“last_name”:1,结果将同时包含_id和last_name。
2. 通过{“_id”:0,“last_name”:1,结果将仅包含last_name 。
3. 通过{“address”:1}结果将包含_id和整个地址对象。
4. 通过{“address.city”:1,结果将包含_id和address对象,该address仅包含city字段。

从MongoDB 4.4开始,你可以使用聚合表达式进行字段投影,如下所示:
例3:使用表达式计算结果字段

query.fields().project(MongoExpression.create("'$toUpper' : '$last_name'"))         --------1.as("last_name");                                                     --------2query.fields().project(StringOperators.valueOf("lastname").toUpper())               --------3.as("last_name");query.fields().project(AggregationSpELExpression.expressionOf("toUpper(lastname)")) --------4.as("last_name");1. 使用native表达式。使用的字段名称必须引用数据库document中的字段名称。
2. 指定表达式结果投影到的字段名称。生成的字段名称未映射到域模型。
3. 使用聚合表达式。除了native MongoExpression之外,字段名被映射到域模型中使用的字段名。
4.SpELAggregationExpression一起使用可以调用表达式函数。字段名称将映射到域模型中使用的字段名称。

@Query(fields=“…”)允许在存储库级别使用表达式字段投影,如MongoDB 基于JSON的查询方法和字段限制中所述。

三、 其他查询选项

MongoDB提供了各种将元信息(如注释[comment]或批处理大小)应用于查询的方法。直接使用Query API,这些选项有几种方法。

3.1 Hints

可以通过两种方式应用索引提示(hint),使用索引名称或其字段定义。

template.query(Person.class).matching(query("...").withHint("index-to-use"));template.query(Person.class).matching(query("...").withHint("{ firstname : 1 }"));

3.2 游标批大小Cursor Batch Size

游标批大小定义了每个响应批中要返回的文档数量。

Query query = query(where("firstname").is("luke")).cursorBatchSize(100)

3.3 Collations

在集合操作中使用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);

3.4 读取首选项Read Preference

可以在要运行的Query对象上直接设置要使用的ReadPreference,如下所示。

template.find(Person.class).matching(query(where(...)).withReadPreference(ReadPreference.secondary())).all();

Query实例上的首选项设置将取代MongoTemplate的默认ReadPreference。

3.5 Comments

查询可以配备注释,这使得它们更容易在服务器日志中查找。

template.find(Person.class).matching(query(where(...)).comment("Use the force luke!")).all();

四、查询Distinct值

MongoDB提供了一个操作,通过对结果documents的查询来获得单个字段的distinct值。结果值不需要具有相同的数据类型,该功能也不限于简单类型。对于检索,为了转换和typing,实际的结果类型确实很重要。以下示例展示了如何查询distinct值:
例4:检索distinct值

template.query(Person.class)  --------1.distinct("lastname")       --------2.all();                     --------31. 查询Person集合。
2. 选择lastname字段的distinct值。字段名称是根据域类型属性声明映射的,并考虑到潜在的@Field注解。
3. 将所有distinct值检索为对象列表(由于未指定明确的结果类型)。

将distinct值检索到对象集合中是最灵活的方法,因为它试图确定域类型的属性值,并将结果转换为所需的类型或映射Document结构。
有时,当所需字段的所有值都固定为某个类型时,直接获得正确类型的集合会更方便,如下例所示:
例5:检索强类型的distinct值

template.query(Person.class)  --------1.distinct("lastname")       --------2.as(String.class)           --------3.all();                     --------41. 查询Person的集合。
2. 选择lastname字段的distinct值。字段名是根据域类型属性声明映射的,同时考虑了潜在的@Field注释。
3. 将检索到的值转换为所需的目标类型——在本例中为String。如果存储的字段包含document,也可以将值映射到更复杂的类型。
4.String列表的形式检索所有distinct值。如果无法将类型转换为所需的目标类型,则此方法将抛出DataAccessException

五、GeoSpatial Queries

MongoDB通过使用$ near、$ within、geoWithin和$nearSphere等运算符来支持GeoSpatial查询。“Criteria”类中提供了特定于地理空间查询的方法。还有一些形状类(Box, Circle 和Point)与地理空间相关的“Criteria”方法一起使用。
在MongoDB事务中使用GeoSpatial查询时需要注意,请参阅事务内部的特殊行为。
要了解如何执行GeoSpatial查询,请考虑以下Venue类(取自集成测试并依赖于MappingMongoConverter):
Venue.java

@Document(collection="newyork")
public class Venue {@Idprivate String id;private String name;private double[] location;@PersistenceConstructorVenue(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;}@Overridepublic 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);

要使用球坐标查找圆内的venues,可以使用以下查询:

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内的venues,你可以使用以下查询:

//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);

你可使用下列查询查询,以查询邻近某个点的venues:

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);

要使用球坐标查找点附近的venues,可以使用以下查询:

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 查询

MongoDB 4.2删除了对geoNear命令的支持,该命令以前曾用于运行NearQuery。
Spring Data MongoDB 2.2 MongoOperations#geoNear使用$geoNear aggregation而不是geoNear命令来运行NearQuery。
之前在包装器类型中返回的计算距离(使用geoNear命令时的dis)现在嵌入到生成的document中。如果给定的域类型已经包含具有该名称的属性,则将计算的距离命名为具有潜在随机后缀的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. 包含类型为Number的dis字段的目标类型。

MongoDB支持在数据库中查询地理位置,同时计算与给定原点的距离。使用geo-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 builder API来设置查询,以返回10英里内给定Point周围的所有Restaurant实例。这里使用的Metrics枚举实际上实现了一个接口,以便其他度量也可以插入到距离中。度量由乘法器(multiplier)支持,用于将给定度量的距离值转换为native距离。这里显示的样本将认为10是英里。使用其中一个内置指标(英里和公里)会自动触发在查询中设置球形(spherical)标志。如果要避免这种情况,请将double传递到maxDistance(…)中。有关更多信息,请参阅NearQuery和Distance的JavaDoc。
geo-near操作返回一个封装GeoResult实例的GeoResults包装器对象。包装GeoResults 允许访问所有结果的平均距离。单个GeoResult对象携带找到的实体及其与原点的距离。

七、GeoJSON 支持

MongoDB支持地理空间数据的GeoJSON和简单的(遗留的)坐标对。这些格式既可以用于存储数据,也可以用于查询数据。请参阅MongoDB手册关于GeoJSON支持的部分,了解相关要求和限制。

八、域类中的GeoJSON类型

在域类中使用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对象的坐标表示纬度和经度对,那么经度在前纬度在后。
因此,GeoJsonPoint将getX()作为经度,将getY()作为纬度。

九、存储库查询方法中的GeoJSON 类型

使用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(                              --------2new 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(                              --------4new Polygon(new Point(-73.992514, 40.758934),new Point(-73.961138, 40.760348),new Point(-73.991658, 40.730006)));1. 使用commons类型的存储库方法定义允许使用GeoJSON和遗留格式调用它。
2. 使用GeoJSON类型来使用$geometry运算符。
3. 请注意,GeoJSON多边形需要定义一个闭合环。
4. 使用遗留格式$polygon运算符。

十、度量和距离计算

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使用何种格式,这两种格式服务器都可以接受。
在距离计算上存在巨大差异。使用遗留格式操作类地球球体上的Radians,而GeoJSON格式使用Meters。
为了避免麻烦,请确保将Metric设置为所需的测量单位,以确保正确计算距离。
换句话说:
假设你有5个Documents,如下所示:

{"_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米半径内的所有Documents:
例6:使用GeoJSON的GeoNear

{"$geoNear": {"maxDistance": 400, "num": 10,"near": { type: "Point", coordinates: [-73.99171, 40.738868] },"spherical":true, "key": "location","distanceField": "distance"}
}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. 以米为单位到中心点的最大距离。
2. GeoJSON总是在一个球体上操作。
3. 以米为单位到中心点的距离。

现在,当使用遗留坐标对时,如前所述,是对Radians进行操作。因此,我们在构造$geoNear命令时使用 Metrics#KILOMETERS。Metric可确保距离乘数设置正确。
例7:具有遗留坐标对的GeoNear

{"$geoNear": {"maxDistance": 0.0000627142377,     --------1"distanceMultiplier": 6378.137,     --------2"num": 10,"near": [-73.99171, 40.738868],"spherical":true,                   --------3"key": "location","distanceField": "distance"}
}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. 与中心点的最大距离(弧度)。
2. 距离乘数,所以我们得到千米作为结果距离。
3. 确保我们对2d_sphere索引进行操作。
4. 与中心点的距离(千米)-乘以1000以匹配GeoJSON中的的米。

十一、全文检索

自MongoDB的2.6版本以来,你可以使用$text运算符运行全文查询。TextQuery和TextCriteria中提供了特定于全文查询的方法和操作。在进行全文搜索时,请参阅MongoDB reference以了解其行为和限制。
在实际使用全文搜索之前,必须正确设置搜索索引。有关如何创建索引结构的更多详细信息,请参见文本索引。以下示例展示了如何设置全文搜索:

db.foo.createIndex(
{title : "text",content : "text"
},
{weights : {title : 3}
}
)

搜索coffee cake的查询可以定义并运行如下:
例8:全文查询

Query query = TextQuery.queryText(new TextCriteria().matchingAny("coffee", "cake"));List<Document> page = template.find(query, Document.class);

使用TextQuery.sortByScore根据权重按相关性排序结果。
例9:全文查询-按分数排序

Query query = TextQuery.queryText(new TextCriteria().matchingAny("coffee", "cake")).sortByScore() .includeScore(); List<Document> page = template.find(query, Document.class);1. 使用score属性根据相关性对结果进行排序,这会触发.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按原样接受所提供的搜索词。因此,你可以通过将phrases放在双引号之间(例如"coffee cake")或使用TextCriteria.phrase来定义。以下示例展示了定义phrase的两种方法:

// search for phrase 'coffee cake'
TextQuery.queryText(new TextCriteria().matching("\"coffee cake\""));
TextQuery.queryText(new TextCriteria().phrase("coffee cake"));

你可以通过在TextCriteria上使用相应的方法来设置$ caseSensitive和$diacriticSensitive 的flags。请注意,这两个可选标志是在MongoDB 3.2中引入的,除非显式设置,否则不会包含在查询中。

十二、Query by Example

“Query by Example”可用于Template API级运行example查询。
以下片段展示了如何通过example进行查询:
类型化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] })之类的限制。
通过使用UntypedExampleMatcher,可以绕过默认行为并跳过类型限制。因此,只要字段名称匹配,几乎任何域类型都可以用作创建引用的探针(probe),如下例所示:
例10:非类型化的示例查询

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);

当在ExampleSpec中包含null值时,Spring Data Mongo使用内嵌式document匹配,而不是点表示法(dot notation)属性匹配。这样做会强制内嵌document中的所有属性值和属性顺序进行精确的document 匹配。
如果你将不同的实体存储在单个集合中或选择不编写类型提示(hints),UntypedExampleMatcher可能是你的正确选择。
此外,请记住,使用@TypeAlias需要对MappingContext进行立即初始化。为此,请配置initialEntitySet,以确保读取操作的别名解析正确。
Spring Data MongoDB提供了对不同匹配选项的支持:
StringMatcher 选项

MatchingLogical 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’}}

十三、查询一个集合以匹配JSON Schema

你可以使用schema来查询任何集合中与JSON schema定义的给定结构匹配的文档,如下例所示:
例11:查询与$jsonSchema匹配的文档

MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();template.find(query(matchingDocumentStructure(schema)), Person.class);

请参考JSON Schema一节了解更多关于Spring Data MongoDB的schema支持。

相关文章:

【Spring连载】使用Spring Data访问 MongoDB----Template API 查询Documents

【Spring连载】使用Spring Data访问 MongoDB----Template API 查询Documents 一、 查询集合中的Documents二 选择字段三、 其他查询选项3.1 Hints3.2 游标批大小Cursor Batch Size3.3 Collations3.4 读取首选项Read Preference3.5 Comments 四、查询Distinct值五、GeoSpatial Q…...

git describe

git describe一般用于查看当前提交距离上次最近的tag是什么&#xff0c;并且还可以知道差了多少个commit&#xff0c;在工程实践当中是个非常好用的命令 如果git describe后面什么都不加的话&#xff0c;默认找的是最近的有注释的tag 如何打有注释的tag打注释&#xff1f; g…...

React Switch用法及手写Switch实现

问&#xff1a;如果注册的路由特别多&#xff0c;找到一个匹配项以后还会一直往下找&#xff0c;我们想让react找到一个匹配项以后不再继续了&#xff0c;怎么处理&#xff1f;答&#xff1a;<Switch>独特之处在于它只绘制子元素中第一个匹配的路由元素。 如果没有<Sw…...

PowerShell执行策略:确保脚本安全执行的关键

PowerShell执行策略&#xff1a;确保脚本安全执行的关键 在自动化和脚本任务管理中&#xff0c;PowerShell 是 Windows 系统管理员和自动化工程师的强大工具。但随着这种强大的能力也带来了安全风险&#xff0c;特别是在执行未经验证的脚本时。为了降低这种风险&#xff0c;Po…...

LeetCode 热题 100 | 图论(上)

目录 1 200. 岛屿数量 2 994. 腐烂的橘子 2.1 智障遍历法 2.2 仿层序遍历法 菜鸟做题&#xff0c;语言是 C 1 200. 岛屿数量 解题思路&#xff1a; 遍历二维数组&#xff0c;寻找 “1”&#xff08;若找到则岛屿数量 1&#xff09;寻找与当前 “1” 直接或间接连接在…...

跟着cherno手搓游戏引擎【25】封装2DRenderer,封装shader传参,自定义Texture

封装2DRenderer&#xff1a; Renderer.h: #include"ytpch.h" #include"Renderer.h" #include <Platform/OpenGL/OpenGLShader.h> #include"Renderer2D.h" namespace YOTO {Renderer::SceneData* Renderer::m_SceneData new Renderer::S…...

多个值时 if [ -z 报错 binary operator expected

if [ ! -z "\$client_pid" ]; then 报错: line 23: [: 662: binary operator expected 改成 if [[ ! -z "\$client_pid" ]]; then 即可。 unix - binary operator expected error when checking if a file with full pathname exists - Stack Overflo…...

如何使用ChatGPT创建一份优质简历

目录 第一步&#xff1a;明确目标和重点 第二步&#xff1a;与ChatGPT建立对话 第三步&#xff1a;整理生成的内容 第四步&#xff1a;注重行文风格 第五步&#xff1a;强调成就和量化结果 第六步&#xff1a;个性化和定制 第七步&#xff1a;反复修改和完善 总结 在现…...

k8s(6)

目录 一.kubectl 命令行管理K8S 陈述式资源管理方式&#xff08;可理解成使用一条kubectl命令及其参数选项来实现资源对象的管理操作&#xff09; service的4的基本类型&#xff1a; service的端口 应用发布策略&#xff1a; 声明式资源管理方式&#xff08;可理解成使用…...

自动驾驶框架:自动驾驶汽车定位-感知-规划-决策-控制概述,按照我的架构图理解:决策决定的是速度,规划决定的是路径(架构理解推荐)

1.按照我的架构图理解&#xff1a;决策决定的是速度&#xff0c;规划决定的是路径 参考链接&#xff1a;【自动驾驶】运动规划丨速度规划丨自动驾驶速度规划及状态协调方法 2.下面是参考别人的理解&#xff1a; 自动驾驶汽车定位-感知-规划-决策-控制概述 规划-决策-控制知…...

Gemma

Gemma 1.使用2.RAG3.LoRA3.1LoRA分类任务3.2LoRA中文建模任务 1.使用 首先是去HF下载模型&#xff0c;但一直下载不了&#xff0c;所以去了HF镜像网站&#xff0c;下载gemma需要HF的Token&#xff0c;按照步骤就可以下载。代码主要是Kaggle论坛里面的分享内容。 huggingface-…...

淘宝关键词搜索API、搜索商品接口、商品价格监控

淘宝搜索引擎的工作原理&#xff1a; 淘宝搜索引擎的工作原理是基于搜索引擎的核心技术——爬虫和索引&#xff0c;通过对海量数据的抓取、分析和存储&#xff0c;提供给用户最准确的搜索结果。 具体来说&#xff0c;淘宝搜索引擎的工作流程如下&#xff1a; 企业级api数据…...

vue实现水印功能

目录 一、应用场景 二、实现原理 三、详细开发 1.水印的实现方式 2.防止用户通过控制台修改样式去除水印效果&#xff08;可跳过&#xff0c;有弊端&#xff09; 3.水印的使用 &#xff08;1&#xff09;单页面/全局使用 &#xff08;2&#xff09;全局使用个别页面去掉…...

记录一下我的Ruby On Rails的systemd服务脚本

自己也是一个 ROR 框架的学习者&#xff0c;同时也是 Ruby 的新手。对于如何让 ROR 应用随系统自动启动并不是很了解。在尝试了各种方法之后&#xff0c;我最终找到了一条可行的途径。虽然不确定是否完全正确&#xff0c;但服务已经成功启动了。因此&#xff0c;我决定在这里保…...

【计算机网络】传输层——TCP和UDP详解

文章目录 一. TCP和UDP简介二. UDP 协议详解1. UDP报文格式2. UDP的使用场景 三. TCP 协议详解1. TCP报文格式2. TCP协议的重要机制确认应答&#xff08;保证可靠传输的最核心机制&#xff09;超时重传连接管理&#xff08;三次握手、四次挥手&#xff09;&#xff01;&#xf…...

stm32和嵌入式linux可以同步学习吗?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「stm3的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;如果需要使用STM32&#xff0c;建…...

maven--->maven中的<properties>属性有什么作用?

&#x1f64c;&#x1f64c;&#x1f64c;&#x1f64c;&#x1f64c;&#x1f64c; 在Maven中&#xff0c;元素用于定义项目中可重用的属性值。这些属性值可以在项目的POM文件中被引用&#xff0c;以便在整个项目中统一管理和使用。通过使用元素&#xff0c;可以避免在POM文件…...

android 网络请求总结

1 先看下基础部分&#xff1a; android okhttp网络访问是基于 tcp/ip 的 最上层是应用层的封装&#xff0c;有http&#xff0c;https&#xff08;加密&#xff09;&#xff0c;ftp 下面是socket套接字的封装&#xff0c;就是将ip和端口的封装 在下面就是tcp/udp 在下面 ip协议…...

用 Python 自动化处理无聊的事情

“编程最棒的部分就是看到机器做一些有用的事情而获得的胜利。用 Python 将无聊的事情自动化将所有编程视为这些小小的胜利&#xff1b;它让无聊变得有趣。” Hilary Mason&#xff0c;数据科学家兼 Fast Forward Labs 创始人 “我很享受打破东西然后把它们重新组合起来的乐趣…...

稀疏计算、彩票假说、MoE、SparseGPT

稀疏计算可能是未来10年内最有潜力的深度学习方向之一&#xff0c;稀疏计算模拟了对人脑的观察&#xff0c;人脑在处理信息的时候只有少数神经元在活动&#xff0c;多数神经元是不工作的。而稀疏计算的基本思想是&#xff1a;在计算过程中&#xff0c;将一些不重要的参数设置为…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...