blob: fbe09d223fe818852d328718821b15e67a89a36e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jackrabbit.oak.plugins.document;
import java.util.ArrayList;
import java.util.List;
import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
import org.bson.conversions.Bson;
import org.junit.Ignore;
import org.junit.Test;
import com.mongodb.BasicDBObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.IndexOptions;
/**
* Test directly ran against MongoDB.
*/
public class MongoDbTest {
@Test
@Ignore
public void manyChildNodes() {
MongoConnection c = MongoUtils.getConnection();
MongoDatabase db = c.getDatabase();
MongoUtils.dropCollections(c.getDatabase());
MongoCollection<BasicDBObject> nodes = db.getCollection(Collection.NODES.toString(), BasicDBObject.class);
BasicDBObject index = new BasicDBObject();
// modification time (descending)
index.put("_mod", -1L);
// and then id (ascending)
index.put("_id", 1L);
IndexOptions options = new IndexOptions();
// options.unique(true);
nodes.createIndex(index, options);
// index on (_id, _mod):
// Query plan: { "cursor" : "BtreeCursor _id_1__mod_-1" ,
// "isMultiKey" : false , "n" : 2000 , "nscannedObjects" : 2000 ,
// "nscanned" : 954647 , "nscannedObjectsAllPlans" : 1907080 ,
// "nscannedAllPlans" : 2859727 , "scanAndOrder" : false ,
// "indexOnly" : true , "nYields" : 5 , "nChunkSkips" : 0 ,
// "millis" : 5112 ,...
// Time: 2229 ms
// Count: 2000
// index on (_mod, _id)
// Query plan: { "cursor" : "BtreeCursor _mod_-1__id_1" ,
// "isMultiKey" : false , "n" : 2000 , "nscannedObjects" : 2000 ,
// "nscanned" : 2000 , "nscannedObjectsAllPlans" : 2203 ,
// "nscannedAllPlans" : 2203 , "scanAndOrder" : false ,
// "indexOnly" : true , "nYields" : 0 , "nChunkSkips" : 0 ,
// "millis" : 3 ,...
// Time: 43 ms
// Count: 2000
int children = 1000000;
int perInsert = 1000;
int group = 0;
String parent = "/parent/node/abc";
for (int i = 0; i < children;) {
List<BasicDBObject> inserts = new ArrayList<>();
group++;
for (int j = 0; j < perInsert; j++, i++) {
BasicDBObject doc = new BasicDBObject();
inserts.add(doc);
doc.put("_id", parent + "/node" + i);
doc.put("_mod", group);
}
nodes.insertMany(inserts);
log("inserted " + i + "/" + children);
}
Bson query = Filters.and(
Filters.gte("_mod", group - 1),
Filters.gt("_id", parent + "/"),
Filters.lte("_id", parent + "0")
);
BasicDBObject keys = new BasicDBObject();
keys.put("_id", 1);
FindIterable<BasicDBObject> cursor = nodes.find(query).projection(keys);
int count = 0;
log("Query plan: " + explain(nodes, query));
long time = System.currentTimeMillis();
for (BasicDBObject obj : cursor) {
// dummy read operation (to ensure we did get the data)
obj.get("_id");
count++;
// log(" read " + obj);
}
time = System.currentTimeMillis() - time;
log("Time: " + time + " ms");
log("Count: " + count);
c.close();
}
@Test
@Ignore
public void updateDocument() {
MongoConnection c = MongoUtils.getConnection();
MongoDatabase db = c.getDatabase();
MongoUtils.dropCollections(c.getDatabase());
MongoCollection<BasicDBObject> nodes = db.getCollection(Collection.NODES.toString(), BasicDBObject.class);
BasicDBObject index = new BasicDBObject();
// modification time (descending)
index.put("_mod", -1L);
// and then id (ascending)
index.put("_id", 1L);
IndexOptions options = new IndexOptions();
// options.unique(true);
nodes.createIndex(index, options);
long time;
time = System.currentTimeMillis();
int nodeCount = 4500;
String parent = "/parent/node/abc";
List<BasicDBObject> inserts = new ArrayList<>(nodeCount);
for (int i = 0; i < nodeCount; i++) {
BasicDBObject doc = new BasicDBObject();
inserts.add(doc);
doc.put("_id", parent + "/node" + i);
doc.put("_mod", 0);
doc.put("_counter", 0);
doc.put("x", 10);
}
nodes.insertMany(inserts);
time = System.currentTimeMillis() - time;
System.out.println("insert: " + time);
time = System.currentTimeMillis();
for (int i = 0; i < nodeCount; i++) {
BasicDBObject fields = new BasicDBObject();
// return _id only
fields.put("_id", 1);
FindOneAndUpdateOptions updateOptions = new FindOneAndUpdateOptions()
.projection(fields).upsert(true);
BasicDBObject query = new BasicDBObject(Document.ID, parent + "/node" + i);
BasicDBObject setUpdates = new BasicDBObject();
BasicDBObject incUpdates = new BasicDBObject();
BasicDBObject unsetUpdates = new BasicDBObject();
setUpdates.append("_mod", i);
incUpdates.append("_counter", 1);
unsetUpdates.append("x", "1");
BasicDBObject update = new BasicDBObject();
if (!setUpdates.isEmpty()) {
update.append("$set", setUpdates);
}
if (!incUpdates.isEmpty()) {
update.append("$inc", incUpdates);
}
if (!unsetUpdates.isEmpty()) {
update.append("$unset", unsetUpdates);
}
// 1087 ms (upsert true+false, returnNew = false)
// 1100 ms (returnNew = true)
// DBObject oldNode =
nodes.findOneAndUpdate(query, update, updateOptions);
// 250 ms WriteConcern.NORMAL, NONE
// 891 ms WriteConcern.SAFE
// > 10 s WriteConcern.JOURNAL_SAFE, FSYNC_SAFE
// WriteResult result =
// nodes.update(query, update, /* upsert */ true, /* multi */ false,
// WriteConcern.NORMAL);
}
time = System.currentTimeMillis() - time;
System.out.println("update: " + time);
time = System.currentTimeMillis();
c.close();
}
private static BasicDBObject explain(MongoCollection<BasicDBObject> collection,
Bson query) {
return collection.find(query).modifiers(new BasicDBObject("$explain", true)).first();
}
private static void log(String msg) {
System.out.println(msg);
}
}