【问题标题】:How to find collections by its nested object's objectId in Spring Data using repository interface?如何使用存储库接口在 Spring Data 中通过其嵌套对象的 objectId 查找集合?
【发布时间】:2014-10-15 23:35:29
【问题描述】:

我在 MongoDB 中有一个集合,其中包含这样的项目:

{
    "_id" : ObjectId("53e4d31d1f6b66e5163962e3c"),
    "name" : "bob",
    "nestedObject" : {
        "_id" : ObjectId("53f5a623cb5e4c1ed4f6ce67")
        //more fields...
    }
}

此项目的 Java 表示如下:

public class SomeObject {
    @Id
    private String id;
    private String name;
    private NestedObject nestedObject;

    //getters and setters
}

Repository 接口定义如下:

public interface SomeObjectRepository extends MongoRepository<SomeObject, String> {
    public List<SomeObject> findByName(String name);
    public List<SomeObject> findByNestedObjectId(String id);
    //some other find functions
}

现在,findByName(String name) 正在正常工作,但 findByNestedObjectId(String id) 什么也没返回。

问题是:是否可以使用存储库接口通过其嵌套对象的属性找到集合项?如果没有,解决此问题的推荐方法是什么?是否可以不重新实现整个存储库?

【问题讨论】:

    标签: java spring mongodb spring-data-mongodb


    【解决方案1】:

    nestedObject id 需要转换成一个

     org.bson.types.ObjectId 
    

    然后 ObjectId 可以与存储库方法一起使用

    findAllByNestedObject_Id(ObjectId)
    

    【讨论】:

    • 感谢您的贡献。您能否提供工作示例代码来说明这一点。请查看本指南“How to Answer”以改进它。
    【解决方案2】:

    我将以下内容用于 Spring-boot;对我来说就像魅力一样:

    @Query("nestedObjectProperty.$id : ?0")
    

    【讨论】:

      【解决方案3】:

      这在 1.6.2 spring-data-mongodb 上对我有用。但是最新版本有问题。

      public interface SomeObjectRepository extends MongoRepository<SomeObject, String> {
          public List<SomeObject> findByName(String name);
          @Query("nestedObjectProperty._id : { $oid : ?0}")
          public List<SomeObject> findByNestedObjectId(String id);
          //some other find functions
      }
      

      【讨论】:

        【解决方案4】:

        我已经想出了如何解决这个问题。

        将参数类型改为org.bson.types.ObjectId;来自字符串

        public List<SomeObject> findByNestedObjectId(ObjectId id);
        

        当你调用它时使用

         repositoryName.findByNestedObjectId(new ObjectId(theIdString));
        

        【讨论】:

        • 这适用于我使用 1.8.2 版本。 findByNestdObjectId(String id);不起作用,我必须使用 ObjectId 而不是字符串才能使其工作......
        【解决方案5】:

        如果NestedObject 看起来像这样:

        class NestedObject {
        
          @Id String id;
        }
        

        您输入查询的String 值是有效的ObjectId 查询:

        findByNestdObjectId(String id);
        

        应该可以。如果觉得不方便,请在JIRA 中创建票证并提供一个小测试用例来重现它。

        【讨论】:

        【解决方案6】:

        Spring-data-mongodb 不会在查询操作的嵌套类中自动将 _id 字段转换为 ObjectId 类型。您应该手动转换它。例如:

        public List<SomeObject> findByNestedObjectId(String id) {
            Query query = Query.query(new Criteria("nestedObject._id", convertToObjectId(id)));
            return mongoTemplate.find(query, SomeObject.class);
        }
        
        Object convertToObjectId(Object id) {
            if (id instanceof String && ObjectId.isValid(id)) {
                return new ObjectId(id);
            }
            return id;
        }
        

        【讨论】:

        • 最终我在处理这个存储库的服务中使用了不同的逻辑。在那里我有一个方法getByNestedObjectId,它首先调用NestedObject no = nestedObjectRepo.findOne(id),然后调用SomeObject result = someObjectRepo.findByNestedObject(no)
        • 你不介意这会因为访问数据库 2 次而第二次是更复杂的查询而降低执行效率吗?
        • 这不正确。嵌套的 id 应该会自动转换。也用于查询执行。
        • @Oliver Gierke:我和提问者有同样的经历,如果不正确,我的代码将无济于事。但是很抱歉我犯了一个错误,现在我知道它已经在后一个版本上升级了。 The problem exists at version 1.0.4.
        • 1.0.4 的什么?如果那是 Spring Data MongoDB,那么古代可能是描述该版本的最佳方式:)。当前版本是 1.5.2。
        【解决方案7】:

        您可以使用@Query 指定存储库使用的mongoDB 查询。我不是 100% 下面的查询是准确的,但有一些事情:

        public interface SomeObjectRepository extends MongoRepository<SomeObject, String> {
            public List<SomeObject> findByName(String name);
            @Query("{nestedObject._id : ?0}")
            public List<SomeObject> findByNestedObjectId(String id);
            //some other find functions
        }
        

        【讨论】:

        • 我已经尝试过了,它正在工作,但不适用于_id。只要您通过 _id 以外的任何方式查询数据库,这是一个很好的答案。 ID 的处理方式不同。 mongo shell 中的示例:db.somecollection.find({ 'nestedObject._id' : "magicId"}) 不返回任何内容,而 db.somecollection.find({ 'nestedObject._id' : ObjectId("magicId") }) 正常。我试图将ObjectId(?0) 添加到@Query,但后来我从java 中得到了JSON 解析异常。不过,感谢您的快速回复:)
        • 是否可以在 NestedObject 中添加“@Id nestedObjectId”等?那么查询肯定应该使用它。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 2014-05-18
        • 2019-12-31
        • 1970-01-01
        • 2016-12-19
        相关资源
        最近更新 更多