[英]Spring Boot Data and MongoDB - Filter Subdocument Array Query
我试图使用Spring来查询Mongo存储库并过滤数组子文档。 我已经引用了如何使用mongodb过滤子文档中的数组 ,但是想知道是否有更合适的或java结构化的方法来使用Spring。
我目前正在使用速记存储库接口表示法,但我正在使用未过滤的数组返回完整的文档。
PersonRepository.java
@Repository
public interface PersonRepository extends MongoRepository <Person, String> {
List<Person> findByAddressZipCode(@Param("zip") int zip);
}
Person.java
@Document
public class Person {
@Id
private String id;
private String firstName;
private String lastName;
private List<Address> 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"
}
]
首先,找到你需要添加的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
都应该有默认的空构造函数!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.