I am trying to perform a query time join of two separate indexes, with different document types, using Lucene query time join.
Each index is valid, and they share a common "ID" Long value that allows the join. However, the join query is returning ZERO results.
I must be doing something wrong, any ideas or help greatly appreciated as I have worked on this for several days.
I tried to join the two indexes using a common Long field, but it returns no results.
The following class will build two indexes (from & to) and then attempt to run a join query against them.
package org.test;
import java.io.File;
import java.nio.file.FileSystems;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.StoredField;
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.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.join.JoinUtil;
import org.apache.lucene.search.join.ScoreMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.NIOFSDirectory;
public class LuceneJoinTest {
public static void main(String[] args) {
try {
buildIndex("C:\\Temp\\index\\fromIndex", "fromFieldId", 50);
buildIndex("C:\\Temp\\index\\toIndex", "toFieldId", 10);
searchIndex();
} catch (Throwable t) {
t.printStackTrace();
}
}
public static void buildIndex(String path, String fieldName, int docCount) throws Exception {
System.out.println("buildIndex:" + path);
Analyzer la = new StandardAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(la);
config.setRAMBufferSizeMB(50);
Directory d = new NIOFSDirectory(FileSystems.getDefault().getPath(path));
IndexWriter writer = new IndexWriter(d, config);
for (int i = 1; i <= docCount; i++) {
System.out.println("Created Document:" + i);
Integer id = Integer.valueOf(i);
Document doc = new Document();
FieldType storedOmitNorms = new FieldType(TextField.TYPE_STORED);
storedOmitNorms.setOmitNorms(false);
doc.add(new Field("id", id.toString(), storedOmitNorms));
doc.add(new NumericDocValuesField(fieldName, id.longValue()));
doc.add(new StoredField(fieldName, id.longValue()));
FieldType fieldNotStoredOmitNorms = new FieldType(TextField.TYPE_NOT_STORED);
fieldNotStoredOmitNorms.setOmitNorms(false);
doc.add(new Field("content", "one two three...", fieldNotStoredOmitNorms));
writer.addDocument(doc);
}
writer.close();
}
public static void searchIndex() throws Exception {
Directory fromIndex = FSDirectory.open(new File("C:\\Temp\\index\\fromIndex").toPath());
IndexReader fromReader = DirectoryReader.open(fromIndex);
IndexSearcher fromSearcher = new IndexSearcher(fromReader);
// Test the FROM INDEX
BooleanQuery.Builder fromQueryBuilder = new BooleanQuery.Builder();
Term fromTerm = new Term("content", "two");
fromQueryBuilder.add(new TermQuery(fromTerm), BooleanClause.Occur.MUST);
Query fromQuery = fromQueryBuilder.build();
TopDocs fromResults = fromSearcher.search(fromQuery, 100);
System.out.println("fromSearcher results:" + fromResults.totalHits);
// Test the TO INDEX
Directory toIndex = FSDirectory.open(new File("C:\\Temp\\index\\toIndex").toPath());
IndexReader toReader = DirectoryReader.open(toIndex);
IndexSearcher toSearcher = new IndexSearcher(toReader);
BooleanQuery.Builder toQueryBuilder = new BooleanQuery.Builder();
Term toTerm = new Term("content", "three");
toQueryBuilder.add(new TermQuery(toTerm), BooleanClause.Occur.MUST);
Query toQuery = toQueryBuilder.build();
TopDocs toResults = toSearcher.search(toQuery, 100);
System.out.println("toSearcher results:" + toResults.totalHits);
// Now test with a JOIN...
Query joinQuery = JoinUtil.createJoinQuery("fromFieldId", false, "toFieldId", Long.class, fromQuery,
fromSearcher, ScoreMode.None);
TopDocs joinResults = toSearcher.search(joinQuery, 100);
System.out.println("joinResults:" + joinResults.totalHits);
}
}
You need to sign in to view this answers