使用 Lucene 搜索的 Cloudant 无法按预期排序
Cloudant With Lucene Search Fails To Sort As Expected
我是 Cloudant 的新手,但在 DB2 上使用 SQL 开发了一段时间。我 运行 遇到一个问题,我认为我正在使用 Lucene 查询引擎和 Cloudant 索引来 return 我的查询结果。查询得到了我想要的所有结果,但是它们没有正确排序。我想根据 "officialName" 字段按字母顺序对结果进行排序。因为我们只 return 处理 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 客户端搜索对象的代码:
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 进行调试,我就可以看到我想要的字段没有被返回。在网上进行了一些挖掘,显然为了排序,该字段必须既有索引又没有标记。因此,我检查了我的索引并注意到该文件正在由 Simple 分析器进行分析。将其更改为关键字,排序按预期进行。希望这对某人有帮助。
我是 Cloudant 的新手,但在 DB2 上使用 SQL 开发了一段时间。我 运行 遇到一个问题,我认为我正在使用 Lucene 查询引擎和 Cloudant 索引来 return 我的查询结果。查询得到了我想要的所有结果,但是它们没有正确排序。我想根据 "officialName" 字段按字母顺序对结果进行排序。因为我们只 return 处理 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 客户端搜索对象的代码:
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 进行调试,我就可以看到我想要的字段没有被返回。在网上进行了一些挖掘,显然为了排序,该字段必须既有索引又没有标记。因此,我检查了我的索引并注意到该文件正在由 Simple 分析器进行分析。将其更改为关键字,排序按预期进行。希望这对某人有帮助。