Mongodb 找到一个元素';没有双向引用的最高级别的祖先
我使用MongoDB在类别中存储子类别,并在子类别中存储项目。我想按项目检索主类别。如何在Spring数据中以最简单的方式实现这一点,而无需双向引用Mongodb 找到一个元素';没有双向引用的最高级别的祖先,mongodb,spring-data,spring-data-mongodb,Mongodb,Spring Data,Spring Data Mongodb,我使用MongoDB在类别中存储子类别,并在子类别中存储项目。我想按项目检索主类别。如何在Spring数据中以最简单的方式实现这一点,而无需双向引用 class Category { private String id; //some other attributes @DbRef List<Category> subCategories = new ArrayList<>(); @DbRef List<
class Category {
private String id;
//some other attributes
@DbRef
List<Category> subCategories = new ArrayList<>();
@DbRef
List<Item> items = new ArrayList<>();
}
我希望通过子类别2提供itemID 001(它是Items集合中的一个项目)来查找ID为1的类别,而不假设连接的深度
我更喜欢使用Spring数据存储库的智能方法命名的惰性方式,比如Category findBySubCategoriesItems(Item Item)
,但是@Query
也非常受欢迎
编辑:我可以通过itemId从MongoDB控制台找到子类别,但我不知道如何递归地升级到根类别。这是我的疑问:
db.category.find({ items: { id: ObjectId("someItemId") } })
我尝试了另一种方法,获取顶级类别并按如下项进行筛选:category.*.items.id:someItemId
,但不幸的是,不支持通配符“any depth”查询,如中所述
编辑2:我一直在阅读关于GraphLookup的文章,但据我所知,只有在设置了父关系时,它才能找到根类别,并且在仅设置了子关系时无法使用它。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"
}
]
}
}
}
}
}
])
你能举一个你的收藏样本吗?@Visrozar我把这个问题扩展了一点来澄清。当你说“连接深度不确定”时,你指的是哪一个收藏(类别还是项目)?假设您谈论的是类别集合,每个类别的子类别数组是否唯一(例如,如果一个类别有2个作为子类别,其他类别是否可以有2个作为子类别)?@Visrozar是的,我谈论的是类别,是的,它们是唯一的,一个子类别只有一个父类别,但此连接仅存储在父类别一侧,子类别不知道其父类别。
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"
}
]
}
}
}
}
}
])