package org.lumongo.test.storage; import com.mongodb.MongoClient; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.IntPoint; import org.apache.lucene.document.LongPoint; import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.SortedSetDocValuesField; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortedSetSortField; import org.apache.lucene.search.TopFieldCollector; import org.apache.lucene.store.Directory; import org.apache.lucene.util.BytesRef; import org.lumongo.storage.lucene.DistributedDirectory; import org.lumongo.storage.lucene.MongoDirectory; import org.lumongo.util.TestHelper; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.io.File; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; import static org.testng.AssertJUnit.assertEquals; public class BasicStorageTest { private static final String STORAGE_TEST_INDEX = "storageTest"; private static Directory directory; @BeforeClass public static void cleanDatabaseAndInit() throws Exception { MongoClient mongo = TestHelper.getMongo(); mongo.dropDatabase(TestHelper.TEST_DATABASE_NAME); directory = new DistributedDirectory(new MongoDirectory(mongo, TestHelper.TEST_DATABASE_NAME, STORAGE_TEST_INDEX, false)); StandardAnalyzer analyzer = new StandardAnalyzer(); IndexWriterConfig config = new IndexWriterConfig(analyzer); IndexWriter w = new IndexWriter(directory, config); addDoc(w, "Random perl Title that is long", "id-1"); addDoc(w, "Random java Title that is long", "id-1"); addDoc(w, "MongoDB is awesome", "id-2"); addDoc(w, "This is a long title with nothing interesting", "id-3"); addDoc(w, "Java is awesome", "id-4"); addDoc(w, "Really big fish", "id-5"); w.commit(); w.close(); } @AfterClass public static void closeDirectory() throws Exception { directory.close(); } private static void addDoc(IndexWriter w, String title, String uid) throws IOException { Document doc = new Document(); doc.add(new TextField("title", title, Field.Store.YES)); doc.add(new TextField("uid", uid, Field.Store.YES)); doc.add(new StringField("uid", uid, Field.Store.YES)); doc.add(new IntPoint("testIntField", 3)); long date = System.currentTimeMillis(); doc.add(new LongPoint("date", date)); doc.add(new NumericDocValuesField("date", date)); doc.add(new SortedSetDocValuesField("category", new BytesRef("Anything"))); Term uidTerm = new Term("uid", uid); w.updateDocument(uidTerm, doc); } private static int runQuery(IndexReader indexReader, QueryParser qp, String queryStr, int count) throws IOException, ParseException { Query q = qp.parse(queryStr); return runQuery(indexReader, count, q); } private static int runQuery(IndexReader indexReader, int count, Query q) throws IOException { long start = System.currentTimeMillis(); IndexSearcher searcher = new IndexSearcher(indexReader); Sort sort = new Sort(); sort.setSort(new SortedSetSortField("category", false)); TopFieldCollector collector = TopFieldCollector.create(sort, count, null, true, true, true); searcher.search(q, collector); ScoreDoc[] hits = collector.topDocs().scoreDocs; int totalHits = collector.getTotalHits(); @SuppressWarnings("unused") long searchTime = System.currentTimeMillis() - start; start = System.currentTimeMillis(); List<String> ids = new ArrayList<>(); for (ScoreDoc hit : hits) { int docId = hit.doc; Document d = searcher.doc(docId); ids.add(d.get("uid")); } @SuppressWarnings("unused") long fetchTime = System.currentTimeMillis() - start; return totalHits; } @Test public void test2Query() throws IOException, ParseException { IndexReader indexReader = DirectoryReader.open(directory); StandardAnalyzer analyzer = new StandardAnalyzer(); QueryParser qp = new QueryParser("title", analyzer) { @Override protected Query getRangeQuery(final String fieldName, final String start, final String end, final boolean startInclusive, final boolean endInclusive) throws ParseException { if ("testIntField".equals(fieldName)) { int startInt = Integer.parseInt(start); int endInt = Integer.parseInt(end); if (!startInclusive) { startInt += 1; } if (!endInclusive) { endInt -= 1; } return IntPoint.newRangeQuery(fieldName, startInt, endInt); } // return default return super.getRangeQuery(fieldName, start, end, startInclusive, endInclusive); } @Override protected Query newTermQuery(org.apache.lucene.index.Term term) { String field = term.field(); String text = term.text(); if ("testIntField".equals(field)) { int value = Integer.parseInt(text); return IntPoint.newExactQuery(field, value); } return super.newTermQuery(term); } }; qp.setAllowLeadingWildcard(true); int hits; hits = runQuery(indexReader, qp, "java", 10); assertEquals("Expected 2 hits", 2, hits); hits = runQuery(indexReader, qp, "perl", 10); assertEquals("Expected 0 hits", 0, hits); hits = runQuery(indexReader, qp, "treatment", 10); assertEquals("Expected 0 hits", 0, hits); hits = runQuery(indexReader, qp, "long", 10); assertEquals("Expected 2 hits", 2, hits); hits = runQuery(indexReader, qp, "MongoDB", 10); assertEquals("Expected 1 hit", 1, hits); hits = runQuery(indexReader, qp, "java AND awesome", 10); assertEquals("Expected 1 hit", 1, hits); hits = runQuery(indexReader, qp, "testIntField:1", 10); assertEquals("Expected 0 hits", 0, hits); hits = runQuery(indexReader, qp, "testIntField:3", 10); assertEquals("Expected 5 hits", 5, hits); hits = runQuery(indexReader, qp, "testIntField:[1 TO 10]", 10); assertEquals("Expected 5 hits", 5, hits); indexReader.close(); } @Test public void test3Api() throws Exception { String hostName = TestHelper.getMongoServer(); String databaseName = TestHelper.TEST_DATABASE_NAME; { MongoClient mongo = new MongoClient(hostName); Directory directory = new DistributedDirectory(new MongoDirectory(mongo, databaseName, STORAGE_TEST_INDEX)); StandardAnalyzer analyzer = new StandardAnalyzer(); IndexWriterConfig config = new IndexWriterConfig(analyzer); IndexWriter w = new IndexWriter(directory, config); boolean applyDeletes = true; IndexReader ir = DirectoryReader.open(w, applyDeletes, false); ir.close(); w.commit(); w.close(); directory.close(); } { MongoClient mongo = new MongoClient(hostName); Directory d = new DistributedDirectory(new MongoDirectory(mongo, databaseName, STORAGE_TEST_INDEX)); IndexReader indexReader = DirectoryReader.open(d); indexReader.close(); d.close(); } { MongoClient mongo = new MongoClient(hostName); DistributedDirectory d = new DistributedDirectory(new MongoDirectory(mongo, databaseName, STORAGE_TEST_INDEX)); Path directory = Paths.get("/tmp/fsdirectory"); try { Files.walkFileTree(directory, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } }); } catch (Exception e) { } File f = new File("/tmp/fsdirectory"); f.mkdirs(); d.copyToFSDirectory(f.toPath()); d.close(); } } }