MongoDBRepository extends DBSRepositoryBase { @Override public PartialList<State> queryAndFetch(Expression expression, DBSExpressionEvaluator evaluator, OrderByClause orderByClause, int limit, int offset, int countUpTo, boolean deepCopy, boolean fulltextScore) { MongoDBQueryBuilder builder = new MongoDBQueryBuilder( evaluator.pathResolver); DBObject query = builder.walkExpression(expression); addPrincipals(query, evaluator.principals); BasicDBObject orderBy; boolean sortScore = false; if (orderByClause == null) { orderBy = null; } else { orderBy = new BasicDBObject(); for (OrderByExpr ob : orderByClause.elements) { Reference ref = ob.reference; boolean desc = ob.isDescending; String field = builder.walkReference(ref).field; if (!orderBy.containsField(field)) { Object value; if (KEY_FULLTEXT_SCORE.equals(field)) { if (!desc) { throw new RuntimeException("Cannot sort by " + NXQL.ECM_FULLTEXT_SCORE + " ascending"); } sortScore = true; value = new BasicDBObject(MONGODB_META, MONGODB_TEXT_SCORE); } else { value = desc ? MINUS_ONE : ONE; } orderBy.put(field, value); } } if (sortScore && orderBy.size() > 1) { throw new RuntimeException("Cannot sort by " + NXQL.ECM_FULLTEXT_SCORE + " and other criteria"); } } DBObject keys; if (fulltextScore || sortScore) { if (!builder.hasFulltext) { throw new RuntimeException(NXQL.ECM_FULLTEXT_SCORE + " cannot be used without " + NXQL.ECM_FULLTEXT); } keys = new BasicDBObject(KEY_FULLTEXT_SCORE, new BasicDBObject( MONGODB_META, MONGODB_TEXT_SCORE)); } else { keys = null; } if (log.isTraceEnabled()) { log.trace("MongoDB: QUERY " + query + (orderBy == null ? "" : " ORDER BY " + orderBy) + " OFFSET " + offset + " LIMIT " + limit); } List<State> list; long totalSize; DBCursor cursor = coll.find(query, keys).skip(offset).limit(limit); try { if (orderBy != null) { cursor = cursor.sort(orderBy); } list = new ArrayList<>(); for (DBObject ob : cursor) { list.add(bsonToState(ob)); } if (countUpTo == -1) { if (limit == 0) { totalSize = list.size(); } else { totalSize = cursor.count(); } } else if (countUpTo == 0) { totalSize = -1; } else { if (limit == 0) { totalSize = list.size(); } else { totalSize = cursor.copy().limit(countUpTo + 1).count(); } if (totalSize > countUpTo) { totalSize = -2; } } } finally { cursor.close(); } if (log.isTraceEnabled() && list.size() != 0) { log.trace("MongoDB: -> " + list.size()); } return new PartialList<>(list, totalSize); } MongoDBRepository(MongoDBRepositoryDescriptor descriptor); @Override void shutdown(); static MongoClient newMongoClient(
            MongoDBRepositoryDescriptor descriptor); static DBCollection getCollection(
            MongoDBRepositoryDescriptor descriptor, MongoClient mongoClient); static DBCollection getCountersCollection(
            MongoDBRepositoryDescriptor descriptor, MongoClient mongoClient); @Override String generateNewId(); @Override void createState(State state); @Override State readState(String id); @Override List<State> readStates(List<String> ids); @Override void updateState(String id, StateDiff diff); @Override void deleteStates(Set<String> ids); @Override State readChildState(String parentId, String name,
            Set<String> ignored); @Override boolean hasChild(String parentId, String name, Set<String> ignored); @Override List<State> queryKeyValue(String key, String value,
            Set<String> ignored); @Override void queryKeyValueArray(String key, Object value, Set<String> ids,
            Map<String, String> proxyTargets,
            Map<String, Object[]> targetProxies); @Override boolean queryKeyValuePresence(String key, String value,
            Set<String> ignored); @Override PartialList<State> queryAndFetch(Expression expression,
            DBSExpressionEvaluator evaluator, OrderByClause orderByClause,
            int limit, int offset, int countUpTo, boolean deepCopy,
            boolean fulltextScore); static final String DB_NAME; static final String MONGODB_ID; static final String MONGODB_INC; static final String MONGODB_SET; static final String MONGODB_UNSET; static final String MONGODB_PUSH; static final String MONGODB_EACH; static final String MONGODB_META; static final String MONGODB_TEXT_SCORE; }
@Test public void testProxySchemas() throws Exception { DocumentModel folder = new DocumentModelImpl("/", "folder", "Folder"); folder = session.createDocument(folder); DocumentModel doc = new DocumentModelImpl("/", "file", "File"); doc = session.createDocument(doc); DocumentModel proxy = session.publishDocument(doc, folder); session.save(); try { doc.setPropertyValue("info:info", "docinfo"); doc = session.saveDocument(doc); session.save(); } catch (PropertyNotFoundException e) { assertTrue(e.getMessage().contains("info:info")); } assertNull(proxy.getPropertyValue("info:info")); proxy.setPropertyValue("info:info", "proxyinfo"); proxy = session.saveDocument(proxy); session.save(); closeSession(); openSession(); DocumentModel root = session.getRootDocument(); proxy = session.getDocument(proxy.getRef()); assertEquals("proxyinfo", proxy.getPropertyValue("info:info")); String nxql; DocumentModelList list; nxql = "SELECT * FROM Document WHERE info:info = 'proxyinfo' AND ecm:isProxy = 1"; list = session.query(nxql); assertEquals(1, list.size()); nxql = "SELECT * FROM Document WHERE info:info = 'proxyinfo'"; list = session.query(nxql); assertEquals(1, list.size()); nxql = "SELECT * FROM Document WHERE info:info = 'proxyinfo' AND ecm:isProxy = 0"; list = session.query(nxql); assertEquals(0, list.size()); nxql = "SELECT ecm:uuid, info:info FROM File WHERE info:info IS NOT NULL"; IterableQueryResult res = session.queryAndFetch(nxql, "NXQL"); Map<Serializable, String> actual = new HashMap<Serializable, String>(); for (Map<String, Serializable> map : res) { Serializable uuid = map.get("ecm:uuid"); String info = (String) map.get("info:info"); actual.put(uuid.toString(), info); } res.close(); assertEquals(Collections.singletonMap(proxy.getId(), "proxyinfo"), actual); session.copy(folder.getRef(), root.getRef(), "folderCopy"); DocumentModel proxyCopy = session.getDocument(new PathRef( "/folderCopy/file")); assertTrue(proxyCopy.isProxy()); assertEquals("proxyinfo", proxyCopy.getPropertyValue("info:info")); }