【问题标题】:Spring Data Mongo Custom Repository Query with ObjectID带有 ObjectID 的 Spring Data Mongo 自定义存储库查询
【发布时间】:2015-11-19 13:40:22
【问题描述】:

我有一个要实现为 Spring Mongo 存储库的 mongo 查询

db.collection.find({ 'items': 
    { $elemMatch: { 
        'refund.$id' :  ObjectId('5638cab2e4b07ff212618d7e') 
        } 
    }
}) 

我的仓库界面是

@Query("{ 'items': { $elemMatch: { 'refund.$id' :  ObjectId(?0) } } }")
RMA findRMAByItemRefund(String refundId);

它抛出 JSONParseException

Caused by: com.mongodb.util.JSONParseException: 
{ 'items': { $elemMatch: { 'refund.$id' :  ObjectId("_param_0") } } }
                                       ^
    at com.mongodb.util.JSONParser.parse(JSON.java:216)

【问题讨论】:

  • 您是否尝试将参数refundId 绑定到查询参数refund.$id ?如果refund 是另一个实体,您可以尝试refund.id,因为 Spring 会自己进行 id 转换
  • 是的。它有效@JoaoEvangelista Spring 处理转换。非常感谢

标签: java spring mongodb spring-mvc spring-data-mongodb


【解决方案1】:

由于接受的解决方案在我的案例中没有产生任何结果,我不得不找到另一个解决方案,即:

我没有使用通过@Query(...) 定义的自动生成查询功能,而是选择手动构建用于查询mongo 的DBObject,并将该功能定义为接口中的default 实现,从而使其保持“干净” (" - 因为必须引入_query 方法)

注意:此解决方案仅适用于 Java 1.8+

public interface SomeRepository extends MongoRepository<SomeEntity, String> {

    @Query("{'nestedEntity._id': ?0}")
    SomeEntity findByNestedEntityId_DoesntWork(String nestedEntityId);

    @Query("?0")
    SomeEntity _query(DBObject query);

    default SomeEntity findByNestedEntityId(String nestedEntityId) {
        DBObject queryObject = BasicDBObjectBuilder
            .start("nestedEntity._id", new ObjectId(nestedEntityId))
            .get();

        return this._query(queryObject);
    }
}

【讨论】:

    【解决方案2】:

    试试这个

    @Query("{ 'items': { $elemMatch: { 'refund.id' :  ?0 } } }")
    RMA findRMAByItemRefund(String refundId);
    

    根据我的经验,?0 应该是独立的,而不是用作 mongo 函数参数。

    另外,$id 是您自己的假设还是该字段实际上存储为$id。如果没有,我会选择refund.id

    【讨论】:

      【解决方案3】:

      我想我的问题有点不同,但由于我无法在任何地方找到答案,我相信值得一提。 基本上我想通过 ObjectId 和 userId 进行搜索,所以这就是我所做的:

      @Query("{ '_id': ?0, 'userId': ?1 }")
      T findByObjectIdAndUserId(final ObjectId objectId, final Long userId);
      

      【讨论】:

        【解决方案4】:

        这是mongo 文档上的示例对象:

        { 
            "_id" : ObjectId("5c052a43f14008522c1c90c8"), 
            "_class" : "com.gdn.payment.report.entity.ReportDocument", 
            "status" : "DONE", 
            "report" : {
                "id" : ObjectId("5c0508bcf14008460015eb07"), 
                "startDate" : NumberLong(1542795843188), 
                "endDate" : NumberLong(1543568857157), 
                "fields" : [
                    "customerInfo.billingAddress.streetAddress", 
                    "customerInfo.name", 
                    "items[*].name", 
                    "orderId", 
                    "type"
                ]
            }
        }
        

        您可以只使用ObjectId 数据类型来创建用于搜索report.id 的存储库方法,我尝试仅使用字符串但它不起作用,这是我的存储库方法:

        Page<ReportDocument> findByReport_id(ObjectId reportId, Pageable pageable)
        

        要创建ObjectId,您可以使用:

        new ObjectId({input-reportId-string})
        

        【讨论】:

        • 如果接受的解决方案中的 $elemMatch 不适合您,请尝试此解决方案。效果很好!
        【解决方案5】:

        我建议使用 Spring Data Derived Queries。您也可以在顶部使用QueryDsl

        然后您就可以编写更复杂的查询,而无需处理查询语法和解析等次要问题。

        【讨论】:

          猜你喜欢
          • 2016-08-29
          • 2014-05-24
          • 1970-01-01
          • 2018-10-06
          • 2017-09-19
          • 1970-01-01
          • 2019-03-13
          • 2017-11-15
          • 2015-10-29
          相关资源
          最近更新 更多