Spring Data Mongo Custom Repository Query with ObjectID

12,886

Solution 1

Try this

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

From my experience, ?0 should standalone and not used as a mongo function parameter.

Also, is $id your own assumption or the field is actually stored as $id. If not, I will go with refund.id

Solution 2

As the accepted solution did not yield any results in my case, I had to find another solution, that was:

Instead of using the autogenerated query functionality defined via @Query(...) I opted for manually building the DBObject used to query mongo, and defining the functionality as a default implementation in the interface, thus keeping it "clean" (" - because had to introduce a _query method)

Note: This solution only works in 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);
    }
}

Solution 3

I guess my problem was a little different, but since I couldn't find answer anywhere, I believe it's worth mentioning. Basically I wanted to do the search by ObjectId AND userId, so here's what I've done:

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

Solution 4

This is the example object on mongo document:

{ 
    "_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"
        ]
    }
}

You can make the repository method for searching report.id only by using ObjectId data type, I've tried using just string and it cannot work, here are my repository method:

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

for creating ObjectId you can do it using:

new ObjectId({input-reportId-string})
Share:
12,886
Whales
Author by

Whales

Software Engineer

Updated on June 20, 2022

Comments

  • Whales
    Whales almost 2 years

    I have a mongo query I want to implement as a Spring Mongo Repository

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

    My Repository interface is

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

    It throws JSONParseException

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