原标题:Spring认证中国教育管理中心-Spring Data MongoDB教程四(内容来源:Spring中国教育管理中心) 11.5.9.删除文档的方法您可以使用五种重载方法之一从数据库中删除对象: template.remove(tywin, "GOT"); template.remove(query(where("lastname").is("lannister")), "GOT"); template.remove(new Query().limit(3), "GOT"); template.findAllAndRemove(query(where("lastname").is("lannister"), "GOT"); template.findAllAndRemove(new Query().limit(3), "GOT"); _id从关联的集合中删除由它指定的单个实体。 从GOT集合中删除与查询条件匹配的所有文档。 删除GOT集合中的前三个文档。不同于<2>,文档,以除去由它们的标识_id,运行给定的查询,应用sort,limit和skip选择第一,然后在一次在一个单独的步骤中除去所有。 从GOT集合中删除与查询条件匹配的所有文档。与 <3> 不同的是,文档不会被批量删除,而是逐个删除。 删除GOT集合中的前三个文档。与 <3> 不同的是,文档不会被批量删除,而是逐个删除。 11.5.10。乐观锁定该@Version注释在 MongoDB 的上下文中提供类似于 JPA 的语法,并确保更新仅应用于具有匹配版本的文档。因此,version 属性的实际值被添加到更新查询中,如果另一个操作同时更改了文档,则更新不会产生任何影响。在这种情况下, @Documentclass Person { @Id String id; String firstname; String lastname; @Version Long version; } Person daenerys = template.insert(new Person("Daenerys")); Person tmp = template.findOne(query(where("id").is(daenerys.getId())), Person.class); daenerys.setLastname("Targaryen"); template.save(daenerys); template.save(tmp); // throws OptimisticLockingFailureException 最初插入文档。version设置为0。 加载刚刚插入的文档。version还在0。 用 更新文档version = 0。将lastname和设置version为1。 尝试更新先前加载的文档,但仍有version = 0. 操作失败并显示 乐观锁定需要将 设置WriteConcern为ACKNOWLEDGED。否则 从版本 2.2 开始,MongoOperations还包括@Version从数据库中删除实体时的属性。要删除Document没有版本检查使用MongoOperations#remove(Query,…)的替代MongoOperations#remove(Object)。 从版本 2.2 开始,存储库在删除版本化实体时检查确认删除的结果。一 11.6.查询文件您可以使用Query和Criteria类来表达你的queries.They有反映本地MongoDB的运营商名称方法的名称,如lt,lte,is,和others.TheQuery和Criteria类遵循流畅API的风格,让你可以连续使用多个方法标准和查询同时具有易于理解的代码。为了提高可读性,静态导入让您避免使用“new”关键字来创建Query和Criteria实例。您还可以使用从纯 JSON 字符串BasicQuery创建Query实例,如下例所示: 示例 71.从纯 JSON 字符串创建 Query 实例 BasicQuery query = new BasicQuery("{ age : { $lt : 50 }, accounts.balance : { $gt : 1000.00 }}"); List<Person> result = mongoTemplate.find(query, Person.class); Spring MongoDB 还支持 GeoSpatial 查询(参见GeoSpatial Queries部分)和 Map-Reduce 操作(参见Map-Reduce部分)。 11.6.1.查询集合中的文档早些时候,我们看到了如何使用findOne和findById方法检索单个文档MongoTemplate。这些方法返回单个域对象。我们还可以查询要作为域对象列表返回的文档集合。假设我们有许多Person带有名称和年龄的对象作为文档存储在一个集合中,并且每个人都有一个带有余额的嵌入式帐户文档,我们现在可以使用以下代码运行查询: 示例 72. 使用 MongoTemplate 查询文档 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(); 所有的 find 方法都以一个Query对象作为参数。此对象定义用于执行查询的条件和选项。这些标准是通过使用一个Criteria对象来指定的,该对象具有一个静态工厂方法,where用于实例化一个新Criteria对象。我们建议使用静态进口 查询应返回Person满足指定条件的对象列表。本节的其余部分列出了Criteria与QueryMongoDB 中提供的运算符对应的和类的方法。大多数方法返回Criteria对象,为 API 提供流畅的样式。 Criteria 类的方法的Criteria类提供了以下的方法,所有这些都对应于运营商在MongoDB中:
Criteria 类还为地理空间查询提供了以下方法(请参阅GeoSpatial Queries部分以查看它们的实际效果):
Query 类的方法本Query类有提供查询选项的一些额外的方法:
选择字段MongoDB 支持投影查询返回的字段。投影可以根据名称包含和排除字段(_id除非明确排除,否则始终包含该字段)。 示例 73. 选择结果字段 public class Person { @Id String id; String firstname; @Field("last_name") String lastname; Address address; }query.fields().include("lastname"); query.fields().exclude("id").include("lastname") query.fields().include("address") query.fields().include("address.city") 结果将同时包含_id和last_namevia { "last_name" : 1 }。 结果将仅包含last_namevia { "_id" : 0, "last_name" : 1 }。 结果将通过 包含_id整个address对象{ "address" : 1 }。 结果将包含仅包含字段 via的_idand 和address对象。city{ "address.city" : 1 } 从 MongoDB 4.4 开始,您可以使用聚合表达式进行字段投影,如下所示: 示例 74. 使用表达式计算结果字段 query.fields() .project(MongoExpression.create("'$toUpper' : '$last_name'")) .as("last_name"); query.fields() .project(StringOperators.valueOf("lastname").toUpper()) .as("last_name");query.fields() .project(AggregationSpELExpression.expressionOf("toUpper(lastname)")) .as("last_name"); 使用本机表达式。使用的字段名称必须引用数据库文档中的字段名称。 分配表达式结果投影到的字段名称。结果字段名称未映射到域模型。 使用AggregationExpression. 除了 native MongoExpression,字段名称映射到域模型中使用的名称。 使用 SpEL 和 anAggregationExpression来调用表达式函数。字段名称映射到域模型中使用的名称。 @Query(fields="…")允许在Repository级别使用表达式字段投影,如MongoDB JSON-based Query Methods and Field Restriction 中所述。 11.6.2.查询文档的方法查询方法需要指定T返回的目标类型,并且它们使用显式集合名称重载,以便查询应该对返回类型指示的集合以外的集合进行操作。以下查询方法可让您查找一个或多个文档:
11.6.3.查询不同的值MongoDB 提供了一种操作,通过使用来自结果文档的查询来获取单个字段的不同值。结果值不需要具有相同的数据类型,该功能也不限于简单类型。对于检索,实际结果类型对于转换和打字很重要。以下示例显示了如何查询不同的值: 示例 75. 检索不同的值 template.query(Person.class) .distinct("lastname") .all(); 查询Person集合。 选择该lastname字段的不同值。字段名称根据域类型属性声明进行映射,同时考虑了潜在的@Field注释。 将所有不同的值作为Listof检索Object(由于未指定明确的结果类型)。 将不同的值检索到CollectionofObject是最灵活的方式,因为它尝试确定域类型的属性值并将结果转换为所需的类型或映射Document结构。 有时,当所需字段的所有值都固定为某种类型时,直接获取正确类型的 更方便,Collection如下例所示: 示例 76. 检索强类型的不同值 template.query(Person.class) .distinct("lastname") .as(String.class) .all(); 查询 的集合Person。 选择该lastname字段的不同值。字段名根据域类型属性声明进行映射,同时考虑了潜在的@Field注释。 检索到的值将转换为所需的目标类型 - 在本例中为String. 如果存储的字段包含文档,还可以将值映射到更复杂的类型。 检索所有不同的值作为 a Listof String。如果类型无法转换为所需的目标类型,则此方法将抛出DataAccessException. 11.6.4.地理空间查询MongoDB的支持通过使用等运营商的地理空间查询$near,$within,geoWithin,和$nearSphere。Criteria类中提供了特定于地理空间查询的方法。还有一些形状类(Box、Circle和Point)与地理空间相关Criteria方法结合使用。 在 MongoDB 事务中使用 GeoSpatial 查询时需要注意,请参阅事务内的特殊行为。 要了解如何执行 GeoSpatial 查询,请考虑以下Venue类(取自集成测试并依赖于 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,您可以使用以下查询: 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-rightBox 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); 要查找 a 附近的场地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); 近地查询 在 2.2 中改变了! MongoDB 4.2删除了对 geoNear之前用于运行NearQuery. Spring Data MongoDB 2.2MongoOperations#geoNear使用$geoNear 聚合 而不是geoNear命令来运行NearQuery. dis先前在包装器类型中返回的计算距离(使用 geoNear 命令时)现在嵌入到生成的文档中。如果给定的域类型已经包含具有该名称的属性,则计算出的距离将calculated-distance使用一个潜在的随机后缀命名。 目标类型可能包含一个以返回的距离命名的属性,以(另外)将其直接读回域类型,如下所示。 GeoResults<VenueWithDisField> = template.query(Venue.class) .as(VenueWithDisField.class) .near(NearQuery.near(new GeoJsonPoint(-73.99, 40.73), KILOMETERS)) .all(); 用于标识目标集合和潜在查询映射的域类型。 包含distype 字段的目标类型Number。 MongoDB 支持在数据库中查询地理位置并同时计算距给定原点的距离。使用 geo-near 查询,您可以表达诸如“查找周围 10 英里内的所有餐馆”之类的查询。为了让您这样做,MongoOperations提供geoNear(…)了将 aNearQuery作为参数的方法(以及已经熟悉的实体类型和集合),如以下示例所示: 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 设置查询以返回Restaurant给定范围Point内 10 英里范围内的所有实例。Metrics这里使用的枚举实际上实现了一个接口,以便其他度量也可以插入到一定距离。AMetric由乘数支持,以将给定度量的距离值转换为原生距离。此处显示的示例将 10 视为英里。使用内置指标之一(英里和公里)会自动触发要在查询上设置的球形标志。如果您想避免这种情况,请将普通double值传递到maxDistance(…). 欲了解更多信息,请参阅的JavaDoc的NearQuery和Distance。 geo-near 操作返回一个GeoResults封装GeoResult实例的包装器对象。WrappingGeoResults允许访问所有结果的平均距离。单个GeoResult对象携带找到的实体加上它与原点的距离。 |
|
来自: 王先生的内容 > 《Spring国际认证》