question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

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.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
arivazhagan-jeganathancommented, May 27, 2019

@evanchooly thank you so much. That helps!

1reaction
evanchoolycommented, May 27, 2019
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to combine multiple criteria in OR query dynamically in ...
I guess there could be 2 ways to handle your case: first, use List<Criteria> MorphiaQuery query = Stylist.q(); List<Criteria> l = new ...
Read more >
Index (Morphia)
Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. bucket(String, List<?>) - Method in class dev ...
Read more >
Model.java example - Javatips.net
CriteriaContainer; import com.google.code.morphia.query. ... specified * * If user defined customized \@Id field, it's better to override this * method for ...
Read more >
Index (Morphia) - Javadoc Extreme - Javadox
adds the values to an array field if they doesn't already exist in the array ... attach(CriteriaContainer) - Method in class dev.morphia.query.
Read more >
dev.morphia.mapping.cache.EntityCache java examples
getIdField().get(enreplacedy); readMappedField(datastore, mf, enreplacedy, cache, dbObj); if (oldIdValue != null) { // The enreplacedy already had an id set ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found