1, Solr合併索引數據有兩種方法,第一種是1.4版本中引入的,通過CoreAdminHandler來實現,示例如下: http://localhost:8983/solr/admin/cores?action=mergeindexes&core=core0&indexDir=/opt/solr/core1/data/index&indexDir=/opt/solr/core2/data/index 上述命令會將core1和core2的索引合併到core0中去,這裏最值得注意的一點是:一旦合併完成,必須在core0上調用commit操作,否則索引數據的變化對於searchers來說是暫時不可見的,只有等到下次core0重新裝載起來時纔可見。 實現代碼如下:
- /**
- * 合併索引數據
- * @param otherIndexPathList 其他待合併的索引數據路徑
- * @param coreName 合併的目標solr核名稱
- *
- */ private void mergeIndexData(List<String> otherIndexPathList, String coreName) {
- if (null != otherIndexPathList && otherIndexPathList.size() > 0) {
- HttpClient client = new HttpClient();
- client.setConnectionTimeout(20000);
- client.setTimeout(20000);
- client.setHttpConnectionFactoryTimeout(20000);
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < otherIndexPathList.size(); ++i) {
- sb.append("&indexDir=" + otherIndexPathList.get(i) + "/data/index");
- }
- String mergeIndexCMD = "http://" + Constants.LOCAL_ADDRESS + ":" + this.port + "/admin/cores?action=mergeindexes&core="+ coreName;
- if (sb.length() > 0) {
- mergeIndexCMD += sb.toString();
- }
- HttpMethod method = new GetMethod(mergeIndexCMD);
- method.getParams().setContentCharset("GBK");
- method.getParams().setHttpElementCharset("GBK");
- method.getParams().setCredentialCharset("GBK");
- // execute the method.
- try {
- if (client.executeMethod(method) == 200) {
- String response = method.getResponseBodyAsString();
- if (logger.isInfoEnabled()) {
- logger.info("merge result" + response);
- }
- }
- } catch (Exception e) {
- logger.error("合併其他索引數據失敗 " + coreName + ",索引目錄: " + otherIndexPathList, e);
- }
- //commit操作讓合併後的索引對搜索生效
- StreamingUpdateSolrServer httpSolrServer = null;
- httpSolrServer = getSolrServer(Constants.LOCAL_ADDRESS, this.port, coreName);
- try {
- httpSolrServer.commit();
- } catch (Exception e) {
- }
- }
- }
第二種方法是Solr3.3中引入的,也是通過CoreAdminHandler來實現,示例如下:
http://localhost:8983/solr/admin/cores?action=mergeindexes&core=core0&srcCore=core1&srcCore=core2
同第一種方法一樣,一旦合併完成,必須在core0上調用commit操作,否則索引數據的變化對於searchers來說是暫時不可見的,只有等到下次core0重新裝載起來時纔可見。
使用”srcCore”和”indexDir”這兩種方法的區別:
1) 使用”indexDir”參數,你可以合並不是與Solr核相關聯的索引數據,比如通過Lucene直接創建的索引
2) 使用”indexDir”參數,你必須注意索引數據不是直接寫入的,這就意味着如果它是一個solr核的索引,必須要關閉IndexWriter,這樣才能觸發一個commit命令。
3) “indexDir”必須指向solr核所在的主機上的磁盤路徑,這就限制比較多了,而相反,你可以只給srcCore一個solr核的名稱,而不關心它的實際索引路徑在哪。
4) 使用”srcCore”,你必須確保即使源索引數據同時存在寫操作的時候,合併後的索引頁不會損壞。
2, solr索引合併的時候,底層其實調用的還是Lucene,因此你schema.xml中配置的uniqueKeys它並不知道,因此當你對兩個包含相同文檔(由uniqueKey確定)的索引進行合併時,你會得到雙倍的文檔數,solr這個地方應該改下,畢竟你不是簡單的Lucene包裝嘛。。。