我正在使用MongoDB来存储类别中的子类别,以及子类别中的项目。我想按项目检索主要类别。在没有双向引用的情况下,如何在Spring Data中最简单的方法呢?
class Category {
private String id;
//some other attributes
@DbRef
List<Category> subCategories = new ArrayList<>();
@DbRef
List<Item> items = new ArrayList<>();
}
在数据库中,类别集合看起来像:
{
id: 1,
subcategories: [
2, 3
]
},
{
id: 2,
items: [
001
]
}
我想通过子类别2,提供itemID 001(Items集合中的一个项目)来找到ID为1的类别,不假设连接深度。
我更喜欢使用Spring Data Repository的智能方法命名的惰性方式,类似Category findBySubCategoriesItems(Item item)
,但@Query
也很受赞赏!
编辑:我可以通过itemId从MongoDB控制台中找到subCategory,但是我不知道如何递归地升级到根类别。这是我的查询:
db.category.find({ items: { id: ObjectId("someItemId") } })
我尝试进行另一种处理,获取顶级类别并按以下项进行过滤:category.*.items.id : someItemId
,但不幸的是,不支持通配符“任何深度”查询,如{{3 }}
编辑2:我一直在阅读有关GraphLookup的信息,但据我了解,只有设置了父级关系时,它才能找到根类别,而仅设置了子级时,它就不能使用它。
答案 0 :(得分:2)
Graphlookup绝对是必经之路, 假设两个集合的名称分别是“ items”和“ categories”,
db.items.aggregate([
{
// find the item in items collection
$match: {
items: '001'
},
},
// recursively find the categories starting from matched item
{
$graphLookup: {
from: "categories",
startWith: "$id",
connectFromField: "id",
connectToField: "subcategories",
as: "categories",
depthField: "level"
}
},
// get only the root node (this is optional, basically if you skip the below stage, you'll get the entire recursive category list along with the matched item)
{
$project: {
root_category: {
$filter: {
input: "$categories",
as: "category",
cond: {
$eq: [
"$$category.level",
{
$max: "$categories.level"
}
]
}
}
}
}
}
])