2017-10-05 63 views
0

我對Cloudant非常陌生,但是已經在DB2的SQL上開發了一段時間。我遇到了一個問題,我認爲我使用Lucene查詢引擎和Cloudant索引來返回查詢結果。查詢得到我想要的所有結果,但是它們沒有正確排序。我想根據「官方名稱」字段按字母順序對結果進行排序。因爲我們只返回n個結果中的前21個(然後我們有一個js處理程序通過分頁調用更多結果),所以我們不能在java端進行排序,但必須通過Cloudant進行排序。我們的應用程序正在運行Java,並使用IBM的Bluemix和WebSphere Liberty Profile執行。我打包了cloudant-client-2.8.0.jar和cloudant-HTTP-2.8.0.jar文件以訪問Cloudant數據庫。我們有許多正在工作的查詢,因此連接本身很好。Cloudant使用Lucene搜索無法按預期進行排序

下面是構建Cloudant客戶端搜索對象的代碼:

Search search = getCloudantDbForOurApp().search("bySearchPP-ddoc/bySearchPP-indx").includeDocs(true); 
SearchResult<DeliverableDetails> result = search.sort(getSortJsonString(searchString)).querySearchResult(getSearchQuery(searchString), DeliverableDetails.class); 

這裏是方法getSortJsonString。應該指出的是,搜索字符串通常不爲空。我還應該注意,留下或取出-score屬性確實會影響搜索,但從未實現alpha排序結果。

private String getSortJsonString(String searchString) { 
    String sortJson; 
    if (searchString != null && !searchString.isEmpty()) { 
     sortJson = "[\"-<score>\",\"officialName<string>\"]"; 
    } else { 
     sortJson = "\"officialName<string>\""; 
    } 
    return sortJson; 
} 

這裏是getSearchQuery方法的參考相關代碼:

... 
query += "("; 
query += "officialName:" + searchString + "^3"; 
query += " OR " + "deliverableName:" + searchString + "^3"; 
query += " OR " + "alias:" + searchString + "^3"; 
query += " OR " + "contact:" + searchString; 
query += ")"; 
.... 
// The query will look like below, where<search_string> is some user inputted value 
// (officialName:<search_string>*^3 OR deliverableName:<search_string>*^3 OR alias:<search_string>*^3 OR contact:<search_string>*) 

我已經安裝使用Cloudant儀表盤設計文檔和指標如下:

{ 
"_id": "_design/bySearchPP-ddoc", 
"_rev": "4-a91fc4ddeccc998c58adb487a121c168", 
"views": {}, 
"language": "javascript", 
"indexes": { 
    "bySearchPP-indx": { 
    "analyzer": { 
     "name": "perfield", 
     "default": "standard", 
     "fields": { 
     "alias": "simple", 
     "contact": "simple", 
     "deploymentTarget": "keyword", 
     "businessUnit": "keyword", 
     "division": "keyword", 
     "officialName": "simple", 
     "deliverableName": "simple", 
     "pid": "keyword" 
     } 
    }, 
    "index": "function(doc) { 
       if (doc.docType === \"Page\") { 
       index(\"officialName\", doc.officialName, {\"store\":true, \"boost\":4.0}); 
       index(\"deliverableName\", doc.deliverableName, {\"store\":true, \"boost\":3.0}); 
       if (doc.aliases) { 
        for (var i in doc.aliases) { 
        index(\"alias\", doc.aliases[i], {\"store\":true, \"boost\":2.0}); 
        } 
       } 
       if (doc.allContacts) { 
        for (var j in doc.allContacts) { 
        index(\"contact\", doc.allContacts[j], {\"store\":true, \"boost\":0.5}); 
        } 
       } 
       index(\"deploymentTarget\", doc.deploymentTarget, {\"store\":true}); 
       index(\"businessUnit\", doc.businessUnit, {\"store\":true}); 
       index(\"division\", doc.division, {\"store\":true}); 
       index(\"pid\", doc.pid.toLowerCase(), {\"store\":true}); 
      } 
      }" 
    } 
    } 
} 

我不知道如果排序正在工作,只是不工作,我希望如何,或者如果我錯誤配置了某些東西。無論哪種方式,任何幫助將不勝感激。 - 道格

+0

在其中一種情況下,您先按分數排序,然後按官方名稱排序。這不是問題嗎? – markwatsonatx

+0

您可以查看[SearchResultRow](http://static.javadoc.io/com.cloudant/cloudant-client/2.2.0/com/cloudant/client/api/model/SearchResult.SearchResultRow.html)上的順序。查看排序中使用的值。數組中的第一個值對應於排序中使用的第一個值。 (Object obj:row.getOrder()){ System.out.println(obj); } – markwatsonatx

+0

@markwatsonatx - 無論我是否拿出分數標籤,它都無法正常工作。感謝他調試小費。這表明officialName值沒有被返回。做了一些挖掘,我發現該字段已被索引,但不應該被標記。當我將索引表格簡單分析器更改爲關鍵字時,它就起作用了感謝您的提示。 – Doug

回答

1

解決了我自己的問題w /幫助上面的評論。顯然一切都設置正確,但一旦我調試每@ markwatsonatx我可以看到我想要的字段沒有被返回。有一些挖掘在線,顯然是爲了排序領域必須既索引,也不標記。因此,我檢查了我的索引並注意到簡單分析器正在分析這個文件。將其更改爲關鍵字,排序按預期工作。好吧,這有助於某人。

相關問題