Spring认证中国教育管理中心-Spring Data MongoDB教程四

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: Spring认证中国教育管理中心-Spring Data MongoDB教程四

原标题: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 属性的实际值被添加到更新查询中,如果另一个操作同时更改了文档,则更新不会产生任何影响。在这种情况下,
OptimisticLockingFailureException会抛出an 。以下示例显示了这些功能:

@Document
class 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. 操作失败并显示
OptimisticLockingFailureException,因为当前version是1。

乐观锁定需要将 设置WriteConcern为ACKNOWLEDGED。否则
OptimisticLockingFailureException可以被无声吞噬。

从版本 2.2 开始,MongoOperations还包括@Version从数据库中删除实体时的属性。要删除Document没有版本检查使用MongoOperations#remove(Query,…)的替代MongoOperations#remove(Object)。

从版本 2.2 开始,存储库在删除版本化实体时检查确认删除的结果。一
OptimisticLockingFailureException,如果一个版本实体不能被删除,通过提高CrudRepository.delete(Object)。在这种情况下,版本已更改或对象在此期间被删除。使用CrudRepository.deleteById(ID)旁路乐观锁定功能,也不管他们的版本中删除对象。

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对象。我们建议使用静态进口
org.springframework.data.mongodb.core.query.Criteria.where和Query.query使查询更具可读性。

查询应返回Person满足指定条件的对象列表。本节的其余部分列出了Criteria与QueryMongoDB 中提供的运算符对应的和类的方法。大多数方法返回Criteria对象,为 API 提供流畅的样式。

Criteria 类的方法

的Criteria类提供了以下的方法,所有这些都对应于运营商在MongoDB中:

  • Criteria all (Object o)使用$all运算符创建条件
  • Criteria 并将 指定(String key)的链添加到当前并返回新创建的CriteriakeyCriteria
  • Criteria andOperator (Criteria… criteria)使用$and运算符为所有提供的条件创建和查询(需要 MongoDB 2.0 或更高版本)
  • Criteria andOperator (Collection<Criteria> criteria)使用$and运算符为所有提供的条件创建和查询(需要 MongoDB 2.0 或更高版本)
  • Criteria elemMatch (Criteria c)使用$elemMatch运算符创建标准
  • Criteria 存在 (boolean b)使用$exists运算符创建条件
  • Criteria gt (Object o)使用$gt运算符创建标准
  • Criteria gte (Object o)使用$gte运算符创建条件
  • Criteria in (Object… o)使用$invarargs 参数的运算符创建条件。
  • 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运算符为所有提供的条件创建一个 nor 查询
  • Criteria norOperator (Collection<Criteria> criteria)使用$nor运算符为所有提供的条件创建一个 nor 查询
  • Criteria not ()使用$not影响紧随其后的子句的元运算符创建一个条件
  • Criteria orOperator (Criteria… criteria)使用$or运算符为所有提供的条件创建 or 查询
  • Criteria orOperator (Collection<Criteria> criteria)使用$or运算符为所有提供的条件创建 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)创建使用的标准$jsonSchema操作员JSON模式标准。$jsonSchema只能应用于查询的顶层,而不是特定于属性的。使用properties架构的属性来匹配嵌套字段。
  • Criteria bits()是MongoDB 按位查询运算符(如$bitsAllClear.

Criteria 类还为地理空间查询提供了以下方法(请参阅GeoSpatial Queries部分以查看它们的实际效果):

  • Criteria (Circle circle)创建使用地理空间标准$geoWithin $center运算符。
  • Criteria (Box box)创建使用地理空间标准$geoWithin $box操作。
  • Criteria insideSphere (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类有提供查询选项的一些额外的方法:

  • Query addCriteria (Criteria criteria)用于向查询添加附加条件
  • Field fields ()用于定义要包含在查询结果中的字段
  • Query limit (int limit)用于将返回结果的大小限制为提供的限制(用于分页)
  • Query skip (int skip)用于跳过结果中提供的文档数(用于分页)
  • Query with (Sort sort)用于为结果提供排序定义

选择字段

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返回的目标类型,并且它们使用显式集合名称重载,以便查询应该对返回类型指示的集合以外的集合进行操作。以下查询方法可让您查找一个或多个文档:

  • findAll:T从集合中查询类型对象的列表。
  • findOne:将集合上的即席查询的结果映射到指定类型的对象的单个实例。
  • findById:返回给定 ID 和目标类的对象。
  • find:将集合上的即席查询的结果映射到List指定类型的 a 。
  • findAndRemove:将集合上的即席查询的结果映射到指定类型的对象的单个实例。与查询匹配的第一个文档被返回并从数据库中的集合中删除。

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

要查找 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对象携带找到的实体加上它与原点的距离。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
25天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
61 2
|
2月前
|
XML JavaScript Java
Spring Retry 教程
Spring Retry 是 Spring 提供的用于处理方法重试的库,通过 AOP 提供声明式重试机制,不侵入业务逻辑代码。主要步骤包括:添加依赖、启用重试机制、设置重试策略(如异常类型、重试次数、延迟策略等),并可定义重试失败后的回调方法。适用于因瞬时故障导致的操作失败场景。
Spring Retry 教程
|
1月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
详细介绍实现Java Spring Boot FCM推送教程
92 0
|
3月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
176 0
|
1月前
|
存储 关系型数据库 MySQL
一个项目用5款数据库?MySQL、PostgreSQL、ClickHouse、MongoDB区别,适用场景
一个项目用5款数据库?MySQL、PostgreSQL、ClickHouse、MongoDB——特点、性能、扩展性、安全性、适用场景比较
|
2月前
|
存储 NoSQL 关系型数据库
非关系型数据库-MongoDB技术(二)
非关系型数据库-MongoDB技术(二)
|
2月前
|
NoSQL 关系型数据库 MongoDB
非关系型数据库-MongoDB技术(一)
非关系型数据库-MongoDB技术(一)
|
22天前
|
NoSQL Cloud Native atlas
探索云原生数据库:MongoDB Atlas 的实践与思考
【10月更文挑战第21天】本文探讨了MongoDB Atlas的核心特性、实践应用及对云原生数据库未来的思考。MongoDB Atlas作为MongoDB的云原生版本,提供全球分布式、完全托管、弹性伸缩和安全合规等优势,支持快速部署、数据全球化、自动化运维和灵活定价。文章还讨论了云原生数据库的未来趋势,如架构灵活性、智能化运维和混合云支持,并分享了实施MongoDB Atlas的最佳实践。
|
23天前
|
NoSQL Cloud Native atlas
探索云原生数据库:MongoDB Atlas 的实践与思考
【10月更文挑战第20天】本文探讨了MongoDB Atlas的核心特性、实践应用及对未来云原生数据库的思考。MongoDB Atlas作为云原生数据库服务,具备全球分布、完全托管、弹性伸缩和安全合规等优势,支持快速部署、数据全球化、自动化运维和灵活定价。文章还讨论了实施MongoDB Atlas的最佳实践和职业心得,展望了云原生数据库的发展趋势。
|
24天前
|
存储 NoSQL MongoDB
MongoDB 数据库引用
10月更文挑战第20天
14 1