0

I have simple interface with one method:

 Criteria toCriteria(String key, String value)

And next I'd like to have next implementation

public class EqExpression implements Expression
{

     @Override
     public Criteria toCriteria(String key, String value)
     {
        return Criteria.where(key).eq(Pattern.compile(value));
     }
}

}

but there isn't $eq operator. So my questions:

  • Why org.springframework.data.mongodb.core.query.Criteria doesn't have such operator?
  • Is there a way to implement custom Criteria implementation or is there any workaround?

  • For me it would be good to have code like

     @Override
     public Criteria toCriteria(String key, String value)
     {
        //return new BasicDBObject(key, new BasicDBObject("$eq", value)) converted to Criteria
     }
    

In general, my purpose is to implement rest query language and for each operation like gt, lt I have specific implementation of Expression interface.

Request may looks like name=John&age>20

I am building whole query using next code:

List<Criteria> criterias = new ArrayList<Criteria>();
...
while (matcher.find())
    {
        String key = matcher.group(1);
        String operator = matcher.group(2);
        String value = matcher.group(3);
        // get from map appropriate implementation
        criterias.add(expressions.get(operator).toCriteria(key, value));
    }

May be you have any suggestions how to implement it more elegant

Roman Hrytsyshyn
  • 123
  • 1
  • 11
  • docs.spring.io/spring-data/data-mongo/docs/current/api/org/springframework/data/mongodb/core/query/Criteria.html. `is(Object o)` is your equality operator. – s7vr Nov 25 '16 at 14:44
  • @Veeram `is` generates query `{ "name" : "John"}` but I need `{"name": {"$eq": "John"}}` – Roman Hrytsyshyn Nov 25 '16 at 14:47
  • it's the same. It's implicit equals. https://docs.mongodb.com/manual/reference/operator/query/eq/. Check the examples. – s7vr Nov 25 '16 at 14:51
  • @Veeram ohh, thanks a lot, I got it! so does Criteria cover all mongo operations and there isn't need in defining custom ones, yep? – Roman Hrytsyshyn Nov 25 '16 at 15:01
  • No worries. Not for the case you mentioned. – s7vr Nov 25 '16 at 15:02
  • @Veeram hah, ok, but in general? – Roman Hrytsyshyn Nov 25 '16 at 15:05
  • You may need it in cases spring doesn't support the latest mongo version and you can still upgrade to mongo driver to latest version while keeping the same spring mongo db version and then create expression to use operator from latest mongo version that you want to use. – s7vr Nov 25 '16 at 15:09
  • @Veeram how spring mongo db supports creating new expressions, could you provide any links? – Roman Hrytsyshyn Nov 25 '16 at 16:05

1 Answers1

0

using this answer, I was able to create simple $eq Criteria

private Criteria getEqCriteria(String value)
{
    // hack Criteria, because new Criteria().is(value) not working!
    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);
        criteria.put("$eq", value);
        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;
}
Daulet
  • 96
  • 5