Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Morphia's Criteriacontainer overwrites previously set "$or" statement #1278

Closed
tungnduong opened this issue Oct 30, 2018 · 12 comments
Closed
Labels
Milestone

Comments

@tungnduong
Copy link

tungnduong commented Oct 30, 2018

I am using Morphia's Query api, and found that my "or" expression is getting overwritten when the expression takes a certain shape. The full expression that I tried to craft was:

$and: [ 
    { $or: [ { fieldA: "a"}, { fieldB: "b"} ] } ,    // fieldA == a OR fieldB == b
    { $and: [ 
        { fieldC: "c" },                                        // fieldC == c AND (fieldD = d OR fieldE = e)
        { $or: [ { fieldD: "d" }, { fieldE: "e" } ] }
 ]

Here's how I'm building the query:

 query.and(
         query.or(
                 query.criteria("fieldA").equal("A"),
                 query.criteria("fieldB").equal("B")
         ),
         query.and(
                 query.criteria("fieldC").equal("C"),
                 query.or(
                         query.criteria("fieldD").equal("D"),
                         query.criteria("fieldE").equal("E")
                  )
         )
);

The resultant query's toString() form :
{ query: { "$or" : [{ "fieldD" : "D" }, { "fieldE" : "E" }], "fieldC" : "C" }

It's missing the section, "$or: [ {fieldA: A}, { fieldB: B} ]".

I understand that the api modifies the internal state of the query object, and so I suspect that perhaps I'm not using the API correctly. If so, could you please provide some guidance on how my original expression could be built programmatically using the Query object?

I digged into Morphia's CriteriaContainerImpl.java, and saw that the addTo(final DBObject obj) method descends into the nested expression and passes the running DBObject:

} else {
     // no dup field names, don't use $and
     for (final Criteria child : children) {
          child.addTo(obj);  <--- this is the running DBObject
     }
}

Then, when it starts evaluating the child "$or" expression, it replaces the pre-existing "$or" stored in the propagated DBObject:

final BasicDBList or = new BasicDBList();
for (final Criteria child : children) {
    final BasicDBObject container = new BasicDBObject();
    child.addTo(container);
     or.add(container);
}

obj.put("$or", or);

Thanks for your time. If this is not the proper place to be posting this, then please kindly direct me to where I should go for these type of questions.

@evanchooly evanchooly added the bug label Mar 3, 2019
@evanchooly evanchooly added this to the 1.5.0 milestone Mar 3, 2019
@evanchooly
Copy link
Member

Update: I have your bug fixed but it broke a few other tests. I'm investigating.

@evanchooly
Copy link
Member

I've fixed this bug but the actual shape of the document is different than you're expecting. Because the default "join" operation on document elements is an and, they are often dropped from the generated structure. This makes them less noisy and easier to read. To see the shape generated, for your reference if you're interested, you can check out the unit test here and I've included it below as well since the unit test version is condensed.

{
  "$or": [
    {
      "fieldA": "a"
    },
    {
      "fieldB": "b"
    }
  ],
  "fieldC": "c",
  "$or": [
    {
      "fieldD": "d"
    },
    {
      "fieldE": "e"
    }
  ]
}

@tungnduong
Copy link
Author

Thank you!

@evanchooly
Copy link
Member

Of, course! Apologies for the delay.

@arivazhagan-jeganathan
Copy link

@evanchooly , the response from the above query is
{ query: { "$or" : [{ "fieldD" : "d" }, { "fieldE" : "e" }], "fieldC" : "c" } }
It still skips the first $or block. can you please explain is this still an open issue?
posted related question here:
https://stackoverflow.com/questions/56327859/issues-in-generating-mongo-query-using-morphia-with-nested-and-and-or-criteria

@evanchooly
Copy link
Member

Are you on 1.5.2?

@arivazhagan-jeganathan
Copy link

arivazhagan-jeganathan commented May 27, 2019

@evanchooly 1.3.2.. please help if there is any workaround or fix available for this. Or let us know if there is better way of query building to avoid this issue.

@arivazhagan-jeganathan
Copy link

@tungnduong , can you please share if this issue is resolved for you? what is the morphia version you are using?

@evanchooly
Copy link
Member

evanchooly commented May 27, 2019

Well, the issue is marked as fixed in 1.5.0 so if you're not on at least that version, you're not going to have the fix.

@arivazhagan-jeganathan
Copy link

Thanks @evanchooly .. But i see only 1.3.2 is the latest on Maven.
https://mvnrepository.com/artifact/org.mongodb.morphia/morphia/1.3.2.
Can you please let me know if there is a different link for that?

@evanchooly
Copy link
Member

https://morphia.dev/

@arivazhagan-jeganathan
Copy link

@evanchooly thank you so much. That helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants