Author: sseifert
Date: Thu Sep 17 06:00:21 2015
New Revision: 1703494
URL: http://svn.apache.org/r1703494
Log:
SLING-4381/SLING-5024 for query efficiency on listChildren store parentPath as
separate attribute
Modified:
sling/trunk/contrib/nosql/couchbase-resourceprovider/src/main/java/org/apache/sling/nosql/couchbase/resourceprovider/impl/CouchbaseNoSqlAdapter.java
sling/trunk/contrib/nosql/mongodb-resourceprovider/pom.xml
sling/trunk/contrib/nosql/mongodb-resourceprovider/src/main/java/org/apache/sling/nosql/mongodb/resourceprovider/impl/MongoDBNoSqlAdapter.java
Modified:
sling/trunk/contrib/nosql/couchbase-resourceprovider/src/main/java/org/apache/sling/nosql/couchbase/resourceprovider/impl/CouchbaseNoSqlAdapter.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/nosql/couchbase-resourceprovider/src/main/java/org/apache/sling/nosql/couchbase/resourceprovider/impl/CouchbaseNoSqlAdapter.java?rev=1703494&r1=1703493&r2=1703494&view=diff
==============================================================================
---
sling/trunk/contrib/nosql/couchbase-resourceprovider/src/main/java/org/apache/sling/nosql/couchbase/resourceprovider/impl/CouchbaseNoSqlAdapter.java
(original)
+++
sling/trunk/contrib/nosql/couchbase-resourceprovider/src/main/java/org/apache/sling/nosql/couchbase/resourceprovider/impl/CouchbaseNoSqlAdapter.java
Thu Sep 17 06:00:21 2015
@@ -19,11 +19,14 @@
package org.apache.sling.nosql.couchbase.resourceprovider.impl;
import static com.couchbase.client.java.query.Select.select;
+import static com.couchbase.client.java.query.dsl.Expression.s;
+import static com.couchbase.client.java.query.dsl.Expression.x;
import java.util.Iterator;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.nosql.couchbase.client.CouchbaseClient;
import org.apache.sling.nosql.couchbase.client.CouchbaseKey;
import org.apache.sling.nosql.generic.adapter.AbstractNoSqlAdapter;
@@ -34,6 +37,7 @@ import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.error.DocumentAlreadyExistsException;
+import com.couchbase.client.java.query.Index;
import com.couchbase.client.java.query.N1qlParams;
import com.couchbase.client.java.query.N1qlQuery;
import com.couchbase.client.java.query.N1qlQueryResult;
@@ -45,15 +49,9 @@ import com.couchbase.client.java.query.c
*/
public final class CouchbaseNoSqlAdapter extends AbstractNoSqlAdapter {
- /**
- * Property holding path
- */
- public static final String PN_PATH = "path";
-
- /**
- * Property holding properties data
- */
- public static final String PN_DATA = "data";
+ private static final String PN_PATH = "path";
+ private static final String PN_PARENT_PATH = "parentPath";
+ private static final String PN_DATA = "data";
private final CouchbaseClient couchbaseClient;
private final String cacheKeyPrefix;
@@ -64,9 +62,9 @@ public final class CouchbaseNoSqlAdapter
this.couchbaseClient = couchbaseClient;
this.cacheKeyPrefix = cacheKeyPrefix;
- // make sure primary index is present - ignore error if it is already
present
- Bucket bucket = couchbaseClient.getBucket();
- bucket.query(N1qlQuery.simple("CREATE PRIMARY INDEX ON " +
couchbaseClient.getBucketName()));
+ // make sure primary index and index on parentPath is present - ignore
error if it is already present
+ Index.createPrimaryIndex().on(couchbaseClient.getBucketName());
+ Index.createIndex(PN_PARENT_PATH).on(couchbaseClient.getBucketName(),
x(PN_PARENT_PATH));
}
@Override
@@ -97,10 +95,9 @@ public final class CouchbaseNoSqlAdapter
public Iterator<NoSqlData> getChildren(String parentPath) {
Bucket bucket = couchbaseClient.getBucket();
// fetch all direct children of this path
- Pattern directChildren = Pattern.compile("^" +
StringUtils.removeEnd(parentPath, "/") + "/[^/]+$");
N1qlQuery query = N1qlQuery.simple(select("*")
.from(couchbaseClient.getBucketName())
- .where("REGEXP_LIKE(`" + PN_PATH + "`, '" +
directChildren.pattern() + "')"),
+ .where(x(PN_PARENT_PATH).eq(s(parentPath))),
N1QL_PARAMS);
N1qlQueryResult queryResult = bucket.query(query);
handleQueryError(queryResult);
@@ -136,6 +133,12 @@ public final class CouchbaseNoSqlAdapter
envelope.put(PN_PATH, data.getPath());
envelope.put(PN_DATA,
JsonObject.from(data.getProperties(MultiValueMode.LISTS)));
+ // for list-children query efficiency store parent path as well
+ String parentPath = ResourceUtil.getParent(data.getPath());
+ if (parentPath != null) {
+ envelope.put(PN_PARENT_PATH, parentPath);
+ }
+
JsonDocument doc = JsonDocument.create(cacheKey, envelope);
try {
bucket.insert(doc);
Modified: sling/trunk/contrib/nosql/mongodb-resourceprovider/pom.xml
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/nosql/mongodb-resourceprovider/pom.xml?rev=1703494&r1=1703493&r2=1703494&view=diff
==============================================================================
--- sling/trunk/contrib/nosql/mongodb-resourceprovider/pom.xml (original)
+++ sling/trunk/contrib/nosql/mongodb-resourceprovider/pom.xml Thu Sep 17
06:00:21 2015
@@ -69,13 +69,6 @@
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.3.2</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.sling-mock</artifactId>
<version>1.5.0</version>
Modified:
sling/trunk/contrib/nosql/mongodb-resourceprovider/src/main/java/org/apache/sling/nosql/mongodb/resourceprovider/impl/MongoDBNoSqlAdapter.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/nosql/mongodb-resourceprovider/src/main/java/org/apache/sling/nosql/mongodb/resourceprovider/impl/MongoDBNoSqlAdapter.java?rev=1703494&r1=1703493&r2=1703494&view=diff
==============================================================================
---
sling/trunk/contrib/nosql/mongodb-resourceprovider/src/main/java/org/apache/sling/nosql/mongodb/resourceprovider/impl/MongoDBNoSqlAdapter.java
(original)
+++
sling/trunk/contrib/nosql/mongodb-resourceprovider/src/main/java/org/apache/sling/nosql/mongodb/resourceprovider/impl/MongoDBNoSqlAdapter.java
Thu Sep 17 06:00:21 2015
@@ -23,7 +23,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
-import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.nosql.generic.adapter.AbstractNoSqlAdapter;
import org.apache.sling.nosql.generic.adapter.MultiValueMode;
import org.apache.sling.nosql.generic.adapter.NoSqlData;
@@ -44,8 +44,9 @@ import com.mongodb.client.result.UpdateR
*/
public final class MongoDBNoSqlAdapter extends AbstractNoSqlAdapter {
- private static final String ID_PROPERTY = "_id";
- private static final String DATA_PROPERTY = "_data";
+ private static final String PN_PATH = "_id";
+ private static final String PN_PARENT_PATH = "parentPath";
+ private static final String PN_DATA = "data";
private final MongoCollection<Document> collection;
@@ -61,25 +62,24 @@ public final class MongoDBNoSqlAdapter e
@Override
public NoSqlData get(String path) {
- Document wrapper = collection.find(Filters.eq(ID_PROPERTY,
path)).first();
- if (wrapper == null) {
+ Document envelope = collection.find(Filters.eq(PN_PATH, path)).first();
+ if (envelope == null) {
return null;
}
else {
- return new NoSqlData(path, wrapper.get(DATA_PROPERTY,
Document.class), MultiValueMode.LISTS);
+ return new NoSqlData(path, envelope.get(PN_DATA, Document.class),
MultiValueMode.LISTS);
}
}
@Override
public Iterator<NoSqlData> getChildren(String parentPath) {
List<NoSqlData> children = new ArrayList<>();
- Pattern directChildren = Pattern.compile("^" +
Pattern.quote(StringUtils.removeEnd(parentPath, "/")) + "/[^/]+$");
- FindIterable<Document> result =
collection.find(Filters.regex(ID_PROPERTY, directChildren));
- try (MongoCursor<Document> wrappers = result.iterator()) {
- while (wrappers.hasNext()) {
- Document wrapper = wrappers.next();
- String path = wrapper.get(ID_PROPERTY, String.class);
- Document data = wrapper.get(DATA_PROPERTY, Document.class);
+ FindIterable<Document> result =
collection.find(Filters.eq(PN_PARENT_PATH, parentPath));
+ try (MongoCursor<Document> envelopes = result.iterator()) {
+ while (envelopes.hasNext()) {
+ Document envelope = envelopes.next();
+ String path = envelope.get(PN_PATH, String.class);
+ Document data = envelope.get(PN_DATA, Document.class);
children.add(new NoSqlData(path, data, MultiValueMode.LISTS));
}
}
@@ -88,11 +88,17 @@ public final class MongoDBNoSqlAdapter e
@Override
public boolean store(NoSqlData data) {
- Document wrapper = new Document();
- wrapper.put(ID_PROPERTY, data.getPath());
- wrapper.put(DATA_PROPERTY, new
Document(data.getProperties(MultiValueMode.LISTS)));
+ Document envelope = new Document();
+ envelope.put(PN_PATH, data.getPath());
+ envelope.put(PN_DATA, new
Document(data.getProperties(MultiValueMode.LISTS)));
- UpdateResult result = collection.replaceOne(Filters.eq(ID_PROPERTY,
data.getPath()), wrapper, new UpdateOptions().upsert(true));
+ // for list-children query efficiency store parent path as well
+ String parentPath = ResourceUtil.getParent(data.getPath());
+ if (parentPath != null) {
+ envelope.put(PN_PARENT_PATH, parentPath);
+ }
+
+ UpdateResult result = collection.replaceOne(Filters.eq(PN_PATH,
data.getPath()), envelope, new UpdateOptions().upsert(true));
// return true if a new entry was inserted, false if an existing was
replaced
return (result.getMatchedCount() == 0);
@@ -101,7 +107,7 @@ public final class MongoDBNoSqlAdapter e
@Override
public boolean deleteRecursive(String path) {
Pattern descendantsAndSelf = Pattern.compile("^" + Pattern.quote(path)
+ "(/.+)?$");
- DeleteResult result = collection.deleteMany(Filters.regex(ID_PROPERTY,
descendantsAndSelf));
+ DeleteResult result = collection.deleteMany(Filters.regex(PN_PATH,
descendantsAndSelf));
// return true if any document was deleted
return result.getDeletedCount() > 0;