Mongodb 找到一个元素';没有双向引用的最高级别的祖先

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<

我使用MongoDB在类别中存储子类别,并在子类别中存储项目。我想按项目检索主类别。如何在Spring数据中以最简单的方式实现这一点,而无需双向引用

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"
              }
            ]
          }
        }
      }
    }
  }
])