当前位置: 首页 > 面试题库 >

Spring Boot数据和MongoDB-筛选子文档数组查询

子车英达
2023-03-14
问题内容

我正在尝试使用Spring查询Mongo存储库并过滤数组子文档。我已经参考过如何使用mongodb过滤子文档中的数组,但是想知道是否有更合适的方法或Java结构化方法来使用Spring。

我当前正在使用速记存储库接口符号,但是我正在获取未过滤数组的完整文档。

PersonRepository.java

@Repository
public interface PersonRepository extends MongoRepository <Person, String> {
    List<Person> findByAddressZipCode(@Param("zip") int zip);
}

人.java

@Document
public class Person {
    @Id
    private String id;

    private String firstName;
    private String lastName;
    private List<Address> address;
}

地址.java

public class Address {
    private int zip;
}

样本输入

{
 "firstName":"George",
 "lastName":"Washington",
 "address":[{
     "zip":"12345"
  },{
     "zip":"98765"
  },{
     "zip":"12345"
  }]
}

预期产量

{
 "firstName":"George",
 "lastName":"Washington",
 "address":[{
     "zip":"12345"
  },{
     "zip":"12345"
  }]
}

实际产量

{
 "firstName":"George",
 "lastName":"Washington",
 "address":[{
     "zip":"12345"
  },{
     "zip":"98765"
  },{
     "zip":"12345"
  }]
}

问题答案:

好吧,在Spring Data中,这种查询不是trivial

坏消息:
Spring Data Repository没有针对的解决方案MongoDB Aggregation。因此,您无法在MongoRepository中实现任何方法,例如aggregateBy...

好消息:
Spring Data提供了MongoTemplate允许您执行复杂查询的类,就像在标准MongoDB shell中所做的那样。

因此,由于您只想对exclude不符合某些条件的子文档进行分类,因此我们需要定义集合pipelines

我假设:

zip codes are Numeric (In your example is string)
And, to exclude subdocument, we filter by `zip`
There is no any other filter

MongoDB聚合为:

db.person.aggregate([
    {$unwind: "$address"},
    {$match: {"address.zip": 12345}},
    {$group: { _id: { "firstName":"$firstName", "lastName":"$lastName", _id:"$_id" }, address: { $push: "$address" } } },
    {$project: {_id:0, "firstName":"$_id.firstName", "lastName":"$_id.lastName", "address": "$address"}}
])

如果所有筛选器均成功,则我们得到:

[ 
    {
        "address" : [ 
            {
                "zip" : 12345
            }, 
            {
                "zip" : 12345
            }
        ],
        "firstName" : "George",
        "lastName" : "Washington"
    }
]

现在,以Spring Data的方式,您需要在项目中添加一些更改:

首先,找到您mongo-config.xml需要添加的位置:

<!-- Define the mongoDbFactory with your database Name  -->
<mongo:db-factory uri="mongodb://user:pass@localhost:27017/db"/>

<!-- Define the MongoTemplate  -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>

MongoTemplate是Spring的MongoDB支持的核心类,提供与数据库交互的功能集。该模板...提供了 域对象
MongoDB文档 之间的映射。更多信息

其次,在您的@Service课程中,添加以下代码以供加载@PostConstruct

@Autowired
private MongoOperations mongoOperations;

...

public List<Person> findByAddressZipCode(int zip) {

    List<AggregationOperation> list = new ArrayList<AggregationOperation>();
    list.add(Aggregation.unwind("address"));
    list.add(Aggregation.match(Criteria.where("address.zip").is(zip)));
    list.add(Aggregation.group("firstName", "lastName").push("address").as("address"));
    list.add(Aggregation.project("firstName", "lastName", "address"));
    TypedAggregation<Person> agg = Aggregation.newAggregation(Person.class, list);
    return mongoOperations.aggregate(agg, Person.class, Person.class).getMappedResults();
}

注: 这两个,Person并且Address应该有默认的空构造!



 类似资料:
  • b)“Units”字段包含带有“period”字段的子文档(日期对象数组),其中给定的日期位于数组中的第一和第二元素之间。 数据结构如下所示: 我尝试使用.find()和.aggregate()的各种组合,例如在periol数组上使用$project和$filter,在unit._id上使用$elemmatch之后使用$elemmatch,但是没有用--我得到了诸如“不能在数组上使用$filter

  • 我是新来的mongo。我有以下收藏。 文件: 请求: 文档集合中的typeId是文档类型的id,其中请求中的typeId是也可以为空的外部字段。如何获得以下输出。

  • 我有一个问题,就是在MongoDB上使用数组中的范围过滤一个日期。 文件1: 文件2: 简历: 我有2份文件: 文档1(嵌入数组上的2个元素): 项目。0.bookingStart:“2022-03-19T00:00:00.000Z” 文档1(Embed数组上的1个元素): 项目。0.bookingStart:“2022-04-19T00:00:00.000Z” Mongo过滤器: 猫鼬过滤器:

  • 问题内容: 我正在使用MongoDB数据库,该数据库的收集模型包括 班级 , 学生 , 学科 和[学术] 表现 。以下是基于猫鼬的架构和模型: 该集合的文件是最复杂的地段; 示例文档为: 我能够使用以下代码检索现有的班级文档并将其添加到分数中: 但是,如何添加/更新/删除该特定学生的成绩?我需要能够通过以下方式与集合进行交互: 检索所有学生或特定学生的分数(检索数组中的特定元素) 为特定主题添加/

  • 问题 你想要根据布尔条件来筛选数组。 解决方案 使用 Array.filter (ECMAScript 5): array = [1..10] array.filter (x) -> x > 5 # => [6,7,8,9,10] 在 EC5 之前的实现中,可以通过添加一个筛选函数扩展 Array 的原型,该函数接受一个回调并对自身进行过滤,将回调函数返回 true 的元素收集起来。 # 扩展 A

  • 我试图用C#在MongoDB中用嵌套数组文档实现文本搜索功能。我有一个以下格式的MongoDB集合。