使用ObjectID的Spring Data Mongo自定义存储库查询

时间:2015-11-19 13:40:22

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

我想要实现一个mongo查询作为Spring 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)

5 个答案:

答案 0 :(得分:4)

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

我没有使用通过@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);
    }
}

答案 1 :(得分:2)

试试这个

      NSString *displayName = [(NSArray *)[urls valueForKey:@"display_url"] objectAtIndex:i];
      NSURL    *url         = [NSURL URLWithString:[(NSArray *)[urls valueForKey:@"expanded_url"]objectAtIndex:i]];

根据我的经验,@Query("{ 'items': { $elemMatch: { 'refund.id' : ?0 } } }") RMA findRMAByItemRefund(String refundId); 应该是独立的,不能用作mongo函数参数。

此外,?0是您自己的假设,或者该字段实际存储为$id。如果没有,我将使用$id

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

这是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"
        ]
    }
}

您只能通过使用report.id数据类型来使存储库方法用于搜索ObjectId,我尝试仅使用字符串并且无法使用,这是我的存储库方法:

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

要创建ObjectId,可以使用:

new ObjectId({input-reportId-string})

答案 4 :(得分:0)

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

那么您将能够编写更复杂的查询,而不必处理诸如查询语法和解析之类的次要问题。