先看个图吧
注意:上图中的article_id可以理解为一个“外键”
query time join 已经在solr存在一段时间了但是lucene中有这个终归是好事,多一种选择嘛,实现这种关联的document还是很实用的,可以实现部分关联查询;
更新属性的时候也可以设计好结构,更新部分索引了。
这个解释有点费劲,还是看代码吧,
final String idField = "id";
+ final String toField = "productId";
+
+ Directory dir = newDirectory();
+ RandomIndexWriter w = new RandomIndexWriter(
+ random,
+ dir,
+ newIndexWriterConfig(TEST_VERSION_CURRENT,
+ new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
+
+ // 0
+ Document doc = new Document();
+ doc.add(new Field("description", "random text", TextField.TYPE_STORED));
+ doc.add(new Field("name", "name1", TextField.TYPE_STORED));
+ doc.add(new Field(idField, "1", TextField.TYPE_STORED));
+ w.addDocument(doc);
+
+ // 1
+ doc = new Document();
+ doc.add(new Field("price", "10.0", TextField.TYPE_STORED));
+ doc.add(new Field(idField, "2", TextField.TYPE_STORED));
+ doc.add(new Field(toField, "1", TextField.TYPE_STORED));
+ w.addDocument(doc);
+
+ // 2
+ doc = new Document();
+ doc.add(new Field("price", "20.0", TextField.TYPE_STORED));
+ doc.add(new Field(idField, "3", TextField.TYPE_STORED));
+ doc.add(new Field(toField, "1", TextField.TYPE_STORED));
+ w.addDocument(doc);
+
+ // 3
+ doc = new Document();
+ doc.add(new Field("description", "more random text", TextField.TYPE_STORED));
+ doc.add(new Field("name", "name2", TextField.TYPE_STORED));
+ doc.add(new Field(idField, "4", TextField.TYPE_STORED));
+ w.addDocument(doc);
+ w.commit();
+
+ // 4
+ doc = new Document();
+ doc.add(new Field("price", "10.0", TextField.TYPE_STORED));
+ doc.add(new Field(idField, "5", TextField.TYPE_STORED));
+ doc.add(new Field(toField, "4", TextField.TYPE_STORED));
+ w.addDocument(doc);
+
+ // 5
+ doc = new Document();
+ doc.add(new Field("price", "20.0", TextField.TYPE_STORED));
+ doc.add(new Field(idField, "6", TextField.TYPE_STORED));
+ doc.add(new Field(toField, "4", TextField.TYPE_STORED));
+ w.addDocument(doc);
+
+ IndexSearcher indexSearcher = new IndexSearcher(w.getReader());
+ w.close();
+
+ // Search for product
+ Query joinQuery =
+ JoinUtil.createJoinQuery(idField, false, toField, new TermQuery(new Term("name", "name2")), indexSearcher);
+
+ TopDocs result = indexSearcher.search(joinQuery, 10);
+ assertEquals(2, result.totalHits);
+ assertEquals(4, result.scoreDocs[0].doc);
+ assertEquals(5, result.scoreDocs[1].doc);
上面的
JoinUtil.createJoinQuery(idField, false, toField, new TermQuery(new Term("name", "name2")), indexSearcher);
是lucene4.0中的,现在还是alphe版本,
在3.6中没有第二个boolean参数,据说4.0的要比3.6的 query time join快3倍,没验证过。