/**
  * Translates a condition that may be an AND of other conditions. Gathers together conditions
  * that apply to the same field.
  */
 private Map<String, Object> translateAnd(RexNode node0) {
   eqMap.clear();
   multimap.clear();
   for (RexNode node : RelOptUtil.conjunctions(node0)) {
     translateMatch2(node);
   }
   Map<String, Object> map = builder.map();
   for (Map.Entry<String, RexLiteral> entry : eqMap.entrySet()) {
     multimap.removeAll(entry.getKey());
     map.put(entry.getKey(), literalToString(entry.getValue()));
   }
   for (Map.Entry<String, Collection<Pair<String, RexLiteral>>> entry :
       multimap.asMap().entrySet()) {
     Map<String, Object> map2 = builder.map();
     for (Pair<String, RexLiteral> s : entry.getValue()) {
       map2.put(s.left, literalToString(s.right));
     }
     map.put(entry.getKey(), map2);
   }
   return map;
 }
 private Object translateOr(RexNode condition) {
   List<Object> list = new ArrayList<Object>();
   for (RexNode node : RelOptUtil.disjunctions(condition)) {
     list.add(translateAnd(node));
   }
   switch (list.size()) {
     case 1:
       return list.get(0);
     default:
       Map<String, Object> map = builder.map();
       map.put("$or", list);
       return map;
   }
 }
 private String translateMatch(RexNode condition) {
   Map<String, Object> map = builder.map();
   map.put("$match", translateOr(condition));
   return builder.toJsonString(map);
 }