4

I'm building a query to retrieve elements from a mongo collection, using MongoTemplate. The query criteria contains a property with an underscore, that somehow is replaced with '._', making the query always return 0 elements.

Criteria matchingCriteria = Criteria
.where("entries").elemMatch(Criteria.where("app_id").is(appId))

Looking to the logs I can see the generated query as follows:

o.s.data.mongodb.core.MongoTemplate: find using query: { "entries" : { "$elemMatch" : { "app._id" : "5834718ab0"}}} fields: null for class: Ranking in collection: ranking

I've already tried with BasicQuery, slashing underscore with '\\', and using the unicode “app\u005Fid". None of them worked. It's important to note that a collection with name "app" exists in my database.

The behaviour doesn't look standard. When I use another property with an underscore the value is not replaced:

Criteria matchingCriteria = Criteria .where("entries").elemMatch(Criteria.where("unique_app_id").‌​is(appId)) 

The logs:

o.s.data.mongodb.core.MongoTemplate find using query: { "entries" : { "$elemMatch" : { "unique_app_id" : "1131706359"}}} fields: null for class: class Ranking in collection: ranking

entries is an array with collection with the following format:

{
    "instanceId" : "654ba2d16579e",
    "app_id" : "583471adb0",
    "unique_app_id" : "554577506",
    "value" : 169
 }

It's worth mentioning that the same query (without the underscore replacement) works fine in a mongo IDE (Robomongo in this case).

I'm using spring-boot-starter-data-mongodb 1.4.1.RELEASE.

I'm really out of ideas right now.

Any suggestion ?

3
  • 1
    Possible duplicate of Spring-Data-Jpa Repository - Underscore on Entity Column Name Commented Feb 16, 2017 at 11:14
  • Can you add an example entries document to your question? Commented Feb 16, 2017 at 14:31
  • Added to the original question @Keith . Commented Feb 16, 2017 at 14:40

1 Answer 1

4

Per section 3.4.3 of this Spring Data Commons documentation:

As we treat underscore as a reserved character we stongly advise to follow standard Java naming conventions (i.e. not using underscores in property names but camel case instead).

I don't believe you can use an underscore character in the middle of an element's name using Spring. Manual references are named after the referenced collection. Use the document type (collection name in singular) followed by _id ( <document>_id ). This is the only case where you can use underscore in the middle.

Update: Here is an existing pull request for the exact behavior you're seeing, as well as Spring's bug tracker for it.

From the Mongo shell, I can execute the following query with success:

> db.app.findOne({ "entries" : { "$elemMatch" : { "app_id" : "1"}}})
{
    "_id" : ObjectId("58a5bc6afa8dd4ae3097d5f7"),
    "name" : "Keith",
    "entries" : [
        {
            "instanceId" : "654ba2d16579e",
            "app_id" : "1"
        }
    ]
}

So, perhaps the Spring API doesn't split when it finds multiple _ tokens when parsing a criteria, but does split for traversal when parsing one.

Sign up to request clarification or add additional context in comments.

3 Comments

Added some details to original question.
Interesting. What happens if you run the query from the mongo shell?
Check my latest update to my answer. I'd be interested in seeing how Spring reacts if you update a document from app_id to be app__id (two underscores) and updating your query with .elemMatch(Criteria.where("app__id"). It's hard to discount the known bug I referenced -- I strongly suspect it's the culprit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.