hi all, I read these two articles http://blog.mikemccandless.com/2012/01/searching-relational-content-with.html, http://blog.mikemccandless.com/2012/01/tochildblockjoinquery-in-lucene.htmland wrote a test program. But it seems there is some problem. it ends with endless loop. Here is my program, almost copy from that article, the only modification is from BlockJoinQuery to ToParentBlockJoinQuery because I can't find BlockJoinQuery in latest 4.0 dev trunk source tree. another modification is from SocreMode.none to ScoreMode.Avg because when using SocreMode.None, an exception throws: Exception in thread "main" java.lang.IllegalStateException: ScoreMode is None at org.apache.lucene.search.join.ToParentBlockJoinQuery$BlockJoinScorer.swapChildScores(ToParentBlockJoinQuery.java:270) at org.apache.lucene.search.join.ToParentBlockJoinCollector.copyGroups(ToParentBlockJoinCollector.java:251) So I change ScoreMode.None to Avg // BlockJoinQuery skuJoinQuery = new BlockJoinQuery(skuQuery, shirts, // ScoreMode.None); ToParentBlockJoinQuery skuJoinQuery = new ToParentBlockJoinQuery(skuQuery, shirts, ScoreMode.Avg);
Then I run again, it ends up with endless loop in BooleanScorer2: public void score(Collector collector) throws IOException { collector.setScorer(this); while ((doc = countingSumScorer.nextDoc()) != NO_MORE_DOCS) { collector.collect(doc); } } current doc is -1, and countingSumScorer.nextDoc() always return -1! following is my program. btw, what's the status of query time join? what's the relationship of solr's join and lucene's join? -------------my codes------------- public class TestJoin { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { File f=new File("./testindex"); if(!f.exists()){ f.mkdirs(); } Directory dir=FSDirectory.open(f); for(String name:dir.listAll()){ dir.deleteFile(name); } IndexWriterConfig conf=new IndexWriterConfig(Version.LUCENE_40,new WhitespaceAnalyzer(Version.LUCENE_40)); IndexWriter writer=new IndexWriter(dir, conf); FieldType fType=new FieldType(); fType.setIndexed(true); fType.setStored(true); fType.setIndexOptions(IndexOptions.DOCS_AND_FREQS); fType.setTokenized(true); Document shirt=new Document(); shirt.add(new Field("name","three wolf",fType)); shirt.add(new StringField("type", "shirt")); Document sku1=new Document(); sku1.add(new StringField("size","small")); sku1.add(new StringField("color","blue")); Document sku2=new Document(); sku2.add(new StringField("size","small")); sku2.add(new StringField("color","black")); Document sku3=new Document(); sku3.add(new StringField("size","medium")); sku3.add(new StringField("color","black")); Document sku4=new Document(); sku4.add(new StringField("size","large")); sku4.add(new StringField("color","gray")); List<Document> shirtGroup=new ArrayList<Document>(); shirtGroup.add(shirt); shirtGroup.add(sku1); shirtGroup.add(sku2); shirtGroup.add(sku3); shirtGroup.add(sku4); writer.addDocuments(shirtGroup); shirt=new Document(); shirt.add(new Field("name","seven wolf",fType)); shirt.add(new StringField("type", "shirt")); sku1=new Document(); sku1.add(new StringField("size","large")); sku1.add(new StringField("color","blue")); sku2=new Document(); sku2.add(new StringField("size","small")); sku2.add(new StringField("color","black")); shirtGroup=new ArrayList<Document>(); shirtGroup.add(shirt); shirtGroup.add(sku1); shirtGroup.add(sku2); writer.addDocuments(shirtGroup); writer.close(); IndexSearcher searcher=new IndexSearcher(DirectoryReader.open(dir)); Filter shirts = new CachingWrapperFilter(new QueryWrapperFilter( new TermQuery(new Term("type", "shirt")))); BooleanQuery skuQuery = new BooleanQuery(); skuQuery.add(new TermQuery(new Term("size", "small")), Occur.MUST); skuQuery.add(new TermQuery(new Term("color", "black")), Occur.MUST); // BlockJoinQuery skuJoinQuery = new BlockJoinQuery(skuQuery, shirts, // ScoreMode.None); ToParentBlockJoinQuery skuJoinQuery = new ToParentBlockJoinQuery(skuQuery, shirts, ScoreMode.Avg); BooleanQuery query = new BooleanQuery(); query.add(new TermQuery(new Term("name", "wolf")), Occur.MUST); query.add(skuJoinQuery, Occur.MUST); ToParentBlockJoinCollector c = new ToParentBlockJoinCollector( Sort.RELEVANCE, // sort 10, // numHits true, // trackScores false // trackMaxScore ); searcher.search(query, c); Sort skuSort=new Sort(new SortField("size",Type.STRING)); TopGroups hits = c.getTopGroups(skuJoinQuery, skuSort, 0, // offset 10, // maxDocsPerGroup 0, // withinGroupOffset true // fillSortFields ); System.out.println("totalHitCount: " + hits.totalHitCount); System.out.println("totalGroupedHitCount: " + hits.totalGroupedHitCount); for(GroupDocs group:hits.groups){ System.out.println("totalHits: "+group.totalHits); for(ScoreDoc doc:group.scoreDocs){ System.out.println(doc.doc+", "+doc.score); } } } }