List of usage examples for com.mongodb QueryOperators ELEM_MATCH
String ELEM_MATCH
To view the source code for com.mongodb QueryOperators ELEM_MATCH.
Click Source Link
From source file:org.nuxeo.ecm.core.storage.mongodb.MongoDBQueryBuilder.java
License:Apache License
protected DBObject walkAnd(List<Operand> values) { List<Object> list = walkOperandList(values); // check wildcards in the operands, extract common prefixes to use $elemMatch Map<String, List<FieldInfoDBObject>> propBaseKeyToDBOs = new LinkedHashMap<>(); Map<String, String> propBaseKeyToFieldBase = new HashMap<>(); for (Iterator<Object> it = list.iterator(); it.hasNext();) { Object ob = it.next();/* w w w. j a v a 2 s.c om*/ if (ob instanceof FieldInfoDBObject) { FieldInfoDBObject fidbo = (FieldInfoDBObject) ob; FieldInfo fieldInfo = fidbo.fieldInfo; if (fieldInfo.hasWildcard) { if (fieldInfo.fieldSuffix != null && fieldInfo.fieldSuffix.contains("*")) { // a double wildcard of the form foo/*/bar/* is not a problem if bar is an array // TODO prevent deep complex multiple wildcards // throw new QueryParseException("Cannot use two wildcards: " + fieldInfo.prop); } // generate a key unique per correlation for this element match String wildcardNumber = fieldInfo.fieldWildcard; if (wildcardNumber.isEmpty()) { // negative to not collide with regular correlated wildcards wildcardNumber = String.valueOf(-counter.incrementAndGet()); } String propBaseKey = fieldInfo.fieldPrefix + "/*" + wildcardNumber; // store object for this key List<FieldInfoDBObject> dbos = propBaseKeyToDBOs.get(propBaseKey); if (dbos == null) { propBaseKeyToDBOs.put(propBaseKey, dbos = new LinkedList<>()); } dbos.add(fidbo); // remember for which field base this is String fieldBase = fieldInfo.fieldPrefix.replace("/", "."); propBaseKeyToFieldBase.put(propBaseKey, fieldBase); // remove from list, will be re-added later through propBaseKeyToDBOs it.remove(); } } } // generate $elemMatch items for correlated queries for (Entry<String, List<FieldInfoDBObject>> es : propBaseKeyToDBOs.entrySet()) { String propBaseKey = es.getKey(); List<FieldInfoDBObject> fidbos = es.getValue(); if (fidbos.size() == 1) { // regular uncorrelated match list.addAll(fidbos); } else { DBObject elemMatch = new BasicDBObject(); for (FieldInfoDBObject fidbo : fidbos) { // truncate field name to just the suffix FieldInfo fieldInfo = fidbo.fieldInfo; Object value = fidbo.get(fieldInfo.queryField); String fieldSuffix = fieldInfo.fieldSuffix.replace("/", "."); if (elemMatch.containsField(fieldSuffix)) { // ecm:acl/*1/principal = 'bob' AND ecm:acl/*1/principal = 'steve' // cannot match // TODO do better value = "__NOSUCHVALUE__"; } elemMatch.put(fieldSuffix, value); } String fieldBase = propBaseKeyToFieldBase.get(propBaseKey); BasicDBObject dbo = new BasicDBObject(fieldBase, new BasicDBObject(QueryOperators.ELEM_MATCH, elemMatch)); list.add(dbo); } } if (list.size() == 1) { return (DBObject) list.get(0); } else { return new BasicDBObject(QueryOperators.AND, list); } }