0

So from a Criteria we have getCriteriaObject which returns Document and then you are able to do some operations on the document, but then I wanna use the results by converting back to a Criteria, I couldn't really find how.

Of course let's take in consideration complex Criteria with multiple operators etc. Any ideas?

user2137817
  • 1,825
  • 5
  • 28
  • 45
  • What is the definition of a `Criteria` and what is the definition of `Document`? What version of the MongoDB driver are you using. Also, what version of MongoDB database are you using? – barrypicker Feb 28 '20 at 18:52

1 Answers1

0

Short answer: No

Criteria has Querydsl-Like syntax which allows the generation of type-safe queries. Reading from Document may introduce MongoDB incompatible commands or syntax for the current MongoDB version.

Long answer: Yes

We can implement walkaround with Java reflection to add Document key:value into Criteria private fields.
Warning: You assume your Document has compatible operators with correct syntax.

Add this helper method into your class (souce):

public static Criteria from(Document document) {
    Criteria c = new Criteria();

    try {

        Field _criteria = c.getClass().getDeclaredField("criteria");
        _criteria.setAccessible(true);

        @SuppressWarnings("unchecked")
        LinkedHashMap<String, Object> criteria = (LinkedHashMap<String, Object>) _criteria.get(c);

        for (Entry<String, Object> set : document.entrySet()) {
            criteria.put(set.getKey(), set.getValue());
        }

        Field _criteriaChain = c.getClass().getDeclaredField("criteriaChain");
        _criteriaChain.setAccessible(true);

        @SuppressWarnings("unchecked")
        List<Criteria> criteriaChain = (List<Criteria>) _criteriaChain.get(c);
        criteriaChain.add(c);

    } catch (Exception e) {
        // Ignore
    }

    return c;
}

Now create new instance for Criteria from Document:

Criteria newCriteria = from(criteria.getCriteriaObject());

//You have full-compatible Criteria instance
newCriteria.and("foobar").elemMatch(Criteria.where("field").is("value"));
Valijon
  • 12,667
  • 4
  • 34
  • 67