我对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});
}
}"
}
}
}
我不知道如果排序正在工作,只是不工作,我希望如何,或者如果我错误配置了某些东西。无论哪种方式,任何帮助将不胜感激。 - 道格
在其中一种情况下,您先按分数排序,然后按官方名称排序。这不是问题吗? – markwatsonatx
您可以查看[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
@markwatsonatx - 无论我是否拿出分数标签,它都无法正常工作。感谢他调试小费。这表明officialName值没有被返回。做了一些挖掘,我发现该字段已被索引,但不应该被标记。当我将索引表格简单分析器更改为关键字时,它就起作用了感谢您的提示。 – Doug