在没有双向引用的情况下查找元素的最高级别祖先
Find an element's highest level ancestor without having bi-directional reference
我正在使用 MongoDB 在类别中存储子类别,在子类别中存储项目。我想按项目检索主要类别。在没有双向参考的情况下,如何以最简单的方式在 Spring 数据中做到这一点?
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 控制台找到子类别,但我不知道如何递归地进入根类别。这是我的查询:
db.category.find({ items: { id: ObjectId("someItemId") } })
我尝试反过来,获取顶级类别并按如下项目过滤:category.*.items.id : someItemId
但不幸的是不支持通配符 "any depth" 查询,如中所述https://jira.mongodb.org/browse/SERVER-267
编辑 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"
}
]
}
}
}
}
}
])
我正在使用 MongoDB 在类别中存储子类别,在子类别中存储项目。我想按项目检索主要类别。在没有双向参考的情况下,如何以最简单的方式在 Spring 数据中做到这一点?
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 控制台找到子类别,但我不知道如何递归地进入根类别。这是我的查询:
db.category.find({ items: { id: ObjectId("someItemId") } })
我尝试反过来,获取顶级类别并按如下项目过滤:category.*.items.id : someItemId
但不幸的是不支持通配符 "any depth" 查询,如中所述https://jira.mongodb.org/browse/SERVER-267
编辑 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"
}
]
}
}
}
}
}
])