Spring 数据 Mongo 使用 ObjectID 的自定义存储库查询
Spring Data Mongo Custom Repository Query with ObjectID
我有一个 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)
试试这个
@Query("{ 'items': { $elemMatch: { 'refund.id' : ?0 } } }")
RMA findRMAByItemRefund(String refundId);
根据我的经验,?0
应该独立使用,而不是用作 mongo 函数参数。
另外,是$id
你自己的假设还是字段实际存储为$id
。如果没有,我会选择 refund.id
由于接受的解决方案在我的案例中没有产生任何结果,我不得不找到另一个解决方案,即:
我没有使用通过 @Query(...)
定义的自动生成的查询功能,而是选择手动构建用于查询 mongo 的 DBObject
,并将该功能定义为 default
在接口中实现,从而保持它 "clean"
("
- 因为不得不引入一个 _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);
}
}
我想我的问题有点不同,但由于我无法在任何地方找到答案,所以我认为值得一提。
基本上我想通过 ObjectId 和 userId 进行搜索,所以这是我所做的:
@Query("{ '_id': ?0, 'userId': ?1 }")
T findByObjectIdAndUserId(final ObjectId objectId, final Long userId);
这是 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})
我建议在顶部使用 Spring 数据 Derived Queries. You can also use QueryDsl。
然后您就可以编写更复杂的查询,而不必处理查询语法和解析等次要问题。
我有一个 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)
试试这个
@Query("{ 'items': { $elemMatch: { 'refund.id' : ?0 } } }")
RMA findRMAByItemRefund(String refundId);
根据我的经验,?0
应该独立使用,而不是用作 mongo 函数参数。
另外,是$id
你自己的假设还是字段实际存储为$id
。如果没有,我会选择 refund.id
由于接受的解决方案在我的案例中没有产生任何结果,我不得不找到另一个解决方案,即:
我没有使用通过 @Query(...)
定义的自动生成的查询功能,而是选择手动构建用于查询 mongo 的 DBObject
,并将该功能定义为 default
在接口中实现,从而保持它 "clean"
("
- 因为不得不引入一个 _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);
}
}
我想我的问题有点不同,但由于我无法在任何地方找到答案,所以我认为值得一提。 基本上我想通过 ObjectId 和 userId 进行搜索,所以这是我所做的:
@Query("{ '_id': ?0, 'userId': ?1 }")
T findByObjectIdAndUserId(final ObjectId objectId, final Long userId);
这是 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})
我建议在顶部使用 Spring 数据 Derived Queries. You can also use QueryDsl。
然后您就可以编写更复杂的查询,而不必处理查询语法和解析等次要问题。