Spring Boot MongoDb 复杂查询
Posted
技术标签:
【中文标题】Spring Boot MongoDb 复杂查询【英文标题】:Spring boot MongoDb complex query 【发布时间】:2019-10-05 15:32:18 【问题描述】:我一直在学习自己在 Spring Boot 中的 MongoDB 实现。 但是,我遇到了复杂查询的问题。
我找不到任何正确的解决方案来解决如何从 Spring boot 实现对 MongoDB 的复杂查询。
我正在使用MongoRepository
接口实现查询数据库。
假设我有三个集合:
Person - 1 Person 可以拥有许多 Pet。 宠物 - 1 只宠物可以拥有 1 个 PetToy 和 1 个拥有他的人。 PetToy - 1 个 PetToy 可以属于 1 个 Pet。POJO 类如下
我想达到什么目的?
我想查询,它会返回一个 Person,他的宠物有一个玩具 (PetToy),名字叫“Teddy”。
我无法找到一种方法来做到这一点。此外,甚至使用如此复杂的查询是最佳实践,还是在 MongoDB 中编写更多的小查询更好?
POJO:
@Document
@Data
@ToString
public class Person
@Id
private String id;
private String firstname;
private String lastname;
private int age;
@DBRef
private Pet pet;
@Document
@Data
@ToString
public class Pet
@Id
private String id;
private String name;
private int age;
@DBRef
private List<PetToy> toys;
@Document
@Data
@ToString
public class PetToy
@Id
private String id;
private String name;
我尝试过使用 MongoRepositories;但是,我无法进行复杂的查询。
如何从 Spring Boot 向 MongoDB 写入这样的查询?
非常感谢您。
【问题讨论】:
在 Person->Pet 和 Pet->Pet Toys 之间的关系中使用 @DBRef 是否有任何理由代替嵌入属性? 我使用了@DBRef,因为我想知道如何连接来自不同集合的两个文档。这只是一个例子。 【参考方案1】:如果可以使用嵌入属性,类模型应该是:
@Document
@Data
@Builder
public class Person
@Id
private String id;
private String firstName;
private String lastName;
private int age;
private List<Pet> pets;
@Data
@Builder
public class Pet
private String name;
private int age;
private List<PetToy> toys;
@Data
@Builder
public class PetToy
private String name;
具有实现您想要的方法的存储库:
public interface PersonRepository extends MongoRepository<Person, String>
List<Person> getByPetsToysName(String name);
getByPetsToysName 方法基本上在 Person 的属性 Person->pets->toys->name 之间导航。更多信息here.
一个例子
@Configuration
@EnableMongoRepositories
public class TestMongo implements CommandLineRunner
private final PersonRepository repository;
public TestMongo(PersonRepository repository)
this.repository = repository;
@Override
public void run(String... args) throws Exception
repository.save(Person.builder()
.firstName("John")
.lastName("Doe")
.age(20)
.pets(Stream.of(Pet.builder()
.name("Ursa")
.age(1)
.toys(Stream.of(PetToy.builder()
.name("Teddy")
.build())
.collect(Collectors.toList()))
.build())
.collect(Collectors.toList()))
.build());
repository.save(Person.builder()
.firstName("Phillip")
.lastName("Larson")
.age(21)
.pets(Stream.of(Pet.builder()
.name("Bella")
.age(5)
.toys(Stream.of(PetToy.builder()
.name("Lolo")
.build())
.collect(Collectors.toList()))
.build())
.collect(Collectors.toList()))
.build());
List<Person> persons = repository.getByPetsToysName("Teddy");
System.out.println(persons.size());
List<Person> persons1 = repository.getByPetsToysName("Lolo");
System.out.println(persons1.size());
日志:
find using query: "pets.toys.name" : "Teddy" fields: Document for class: class Person in collection: person
如果您想要更复杂的查询,可以查看Spring Data MongoDB docs。
【讨论】:
谢谢,我知道如果可能的话,最好使用 Embedded Documents。在这种情况下,当您必须使用文档引用时,您可能应该使用聚合框架。以上是关于Spring Boot MongoDb 复杂查询的主要内容,如果未能解决你的问题,请参考以下文章
spring boot mongodb 模糊查询,开启事务,获取mongoclient 方法