我真的不知道該怎麼Solr的內部連接的工作,但我們知道,RDB多個連接是大型數據集上效率極低,我可能會寫出來我自己的org.apache.solr.handler.component.QueryComponent,這將在正常搜索後獲得根父級(當然,這種方法要求每個孩子doc都有一個對其根病人的引用)。
如果你選擇走這條路,我會發表一些例子。在我之前的一個Solr項目中,我遇到了類似的(更復雜的 - 本體論)問題。
更簡單的方法(解決此問題時更簡單,而不是整個方法)是將您的架構的這部分完全平坦化並將所有信息(文檔和代碼項)存儲到其父患者中,定期搜索。這更符合Solr(您必須以不同的方式查看Solr模式,這與您的常規RDB規範化模式無關,Solr鼓勵數據冗餘,因此您可以在沒有連接的情況下快速搜索)。
第三種方法是對代表性數據集進行一些連接測試,看看搜索性能如何受到影響。最後,它確實取決於你的整個設置和要求(當然還有測試結果)。
編輯1: 我這麼做了幾年,所以你必須弄清楚事情是否同時發生了變化。
1.創建自定義的請求處理程序
要做到徹底的清潔工作,我建議你通過簡單地複製整個部分與
<requestHandler name="/select" class="solr.SearchHandler"> ... ... </requestHandler>
開始定義自己的請求處理程序(solrconfig.xml中)
然後將name
更改爲對用戶有意義的內容,例如/searchPatients
。
<arr name="components">
<str>patients</str>
<str>facet</str>
<str>mlt</str>
<str>highlight</str>
<str>stats</str>
<str>debug</str>
</arr>
2: 另外,內添加這部分。創建自定義搜索組件
添加到您的solrconfig:
<searchComponent name="patients" class="org.apache.solr.handler.component.PatientQueryComponent"/>
創建PatientQueryComponent類:
下面的源可能有錯誤,因爲我修改了原始的源文本編輯器,並張貼未經測試,但重要的是你得到食譜,而不是完成源,對嗎?我拋出緩存,延遲加載,準備方法,只留下基本邏輯。您必須瞭解性能如何受到影響,然後根據需要調整來源。我的表現還不錯,但我的索引中總共有幾百萬份文件。
public class PatientQueryComponent extends SearchComponent {
...
@Override
public void process(ResponseBuilder rb) throws IOException {
SolrQueryRequest req = rb.req;
SolrQueryResponse rsp = rb.rsp;
SolrParams params = req.getParams();
if (!params.getBool(COMPONENT_NAME, true)) {
return;
}
searcher = req.getSearcher();
// -1 as flag if not set.
long timeAllowed = (long)params.getInt(CommonParams.TIME_ALLOWED, -1);
DocList initialSearchList = null;
SolrIndexSearcher.QueryCommand cmd = rb.getQueryCommand();
cmd.setTimeAllowed(timeAllowed);
cmd.setSupersetMaxDoc(UNLIMITED_MAX_COUNT);
// fire standard query
SolrIndexSearcher.QueryResult result = new SolrIndexSearcher.QueryResult();
searcher.search(result, cmd);
initialSearchList = result.getDocList();
// Set which'll hold patient IDs
List<String> patientIds = new ArrayList<String>();
DocIterator iterator = initialSearchList.iterator();
int id;
// loop through search results
while(iterator.hasNext()) {
// add your if logic (doc type, ...)
id = iterator.nextDoc();
doc = searcher.doc(id); // , fields) you can try lazy field loading and load only patientID filed value into the doc
String patientId = doc.get("patientID") // field that's in child doc and points to its root parent - patient
patientIds.add(patientId);
}
// All all unique patient IDs in TermsFilter
TermsFilter termsFilter = new TermsFilter();
Term term;
for(String pid : patientIds){
term = new Term("patient_ID", pid); // field that's unique (name) to patient and holds patientID
termsFilter.addTerm(term);
}
// get all patients whose ID is in TermsFilter
DocList patientsList = null;
patientsList = searcher.getDocList(new MatchAllDocsQuery(), searcher.convertFilter(termsFilter), null, 0, 1000);
long totalSize = initialSearchList.size() + patientsList.size();
logger.info("Total: " + totalSize);
SolrDocumentList solrResultList = SolrPluginUtils.docListToSolrDocumentList(patientsList, searcher, null, null);
SolrDocumentList solrInitialList = SolrPluginUtils.docListToSolrDocumentList(initialSearchList, searcher, null, null);
// Add patients to the end of the list
for(SolrDocument parent : solrResultList){
solrInitialList.add(parent);
}
// replace initial results in response
SolrPluginUtils.addOrReplaceResults(rsp, solrInitialList);
rsp.addToLog("hitsRef", patientsList.size());
rb.setResult(result);
}
}
謝謝,我已經在3種類型的文件進行搜索,所以它會如果我是最好的可以規範化並存儲它。你可以更多地瞭解一下查詢組件。 – user1185893 2012-07-29 03:13:07
好吧,看看它是如何適合在一起先看看這個:http://wiki.apache.org/solr/SolrRequestHandler – 2012-07-29 08:21:21
然後這個:http://wiki.apache.org/solr/SearchHandler – 2012-07-29 08:22:01