做的一个项目要求有搜索功能,就是用了compass做搜索,但是由于业务的特殊性,导致了compass搜索功能不能实现,考虑使用了js前台拼字符串的方式传递给后台做query String。
具体的业务是这样的,一个档案(lawsuitArchive)实体类是一个主要的实体类,当事人和档案之间的关系如下:
//lawsuitArchive 源码
// 相关当事人
@OneToMany(cascade = CascadeType.ALL, mappedBy = "lawsuitArchive")
private Set<Party> partys = new HashSet<Party>();
而在当事人那边有如下映射:
@ManyToOne(cascade = CascadeType.REFRESH)
@JoinColumn(name = "lawsuitArchiveID")
@SearchableComponent(refAlias="LawsuitArchive")
private LawsuitArchive lawsuitArchive;
但是要求的搜索条件是:在同一个面板中使用同时搜索LawsuitArchive,还有Party的类容,大家都知道compass是基于pojo的搜索。故而要实现这样的搜索势必有点点的困难。
要实现的功能如图:
功能是:如果不输关键字的情况下,可以查到时间段内的所有符合条件的信息,(当事人的信息)。如果关键字存在的话,也要能查到符合条件数据。档案的实现很方便,立马能实现(案号中含有年度,时间段好确定),但是依据当事人档案的映射关系,当事人中没有年度这个属性,无奈之下,在当事人中间增加了一个冗余字段caseNo(案号),以便控制时间段。但是问题又来了。即使有了时间段这个属性,还是很困难的一件事情,因为要同时处理连个alias:LawsuiArchive 和 alias:Party,当然是用Struts2 的MVC结构的话,要的到连个不同的结果,就要返回到两个不同的jsp页面来显示。无奈之下,遍采取了如下的js方式:
function add() { var startTime = document.getElementById("startTime").value.substring(0, 4); var endTime = document.getElementById("endTime").value.substring(0, 4); var archive = document.getElementById("archive").value; var archivestate = document.getElementById("archivestate").value; var field = document.getElementById("field").value; var operation = document.getElementById("operation").value; var keyword = document.getElementById("keyword").value; var contact = document.getElementById("contact").value; var queryStr; if (keyword == "" && startTime == "" && endTime == "") { alert("请输入要检索的关键词,或时间段"); return; } else if (keyword == "" && (startTime != "" || endTime != "")) { if (startTime == "" && endTime != "") { startTime = (new Date()).getYear(); } else { endTime = (new Date()).getYear(); } if (field != "party") {// 如果不是当事人的话 // alert(field);//弹出字段 field = ""; } } var timefieldtext = startTime + "-" + endTime; if (keyword.indexOf(" ") != -1 && "date" != operation && "number" != operation) keyword = "\"" + keyword + "\""; if (field != "" && keyword != "") {// 如果字段是存在的.--关键字也是存在的 if ("~" == operation) { queryStr = " " + field + ":" + keyword + operation + " " + contact; } else if ("leftone" == operation) { queryStr = " " + field + ":" + "?" + keyword + " " + contact; } else if ("rightone" == operation) { queryStr = " " + field + ":" + keyword + "?" + " " + contact; } else if ("bothone" == operation) { queryStr = " " + field + ":" + "?" + keyword + "?" + " " + contact; } else if ("leftmany" == operation) { queryStr = " " + field + ":" + "*" + keyword + " " + contact; } else if ("rightmany" == operation) { queryStr = " " + field + ":" + keyword + "*" + " " + contact; } else if ("bothmany" == operation) { queryStr = " " + field + ":" + "*" + keyword + "*" + " " + contact; } else if ("number" == operation) { var keyw = keyword.split(":"); skeyword = "[" + keyw[0] + " TO " + keyw[1] + "]"; queryStr = " " + field + ":" + skeyword + " " + contact; } else if ("date" == operation) { var keyw = keyword.split(":"); if (keyw.length == 1) keyw = keyword.split(":"); var patrn = /^[1-2]{1}[0-9]{1}[0-9]{1}[0-9]{1}-[0-1]{1}[0-9]{1}-[0-3]{1}[0-9]{1}$/; String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); } if (!patrn.exec(keyw[0].trim()) || !patrn.exec(keyw[1].trim())) { alert("日期格式不正确,必须为1900-02-12格式"); return; } skeyword = "[" + keyw[0] + " TO " + keyw[1] + "]"; queryStr = " " + field + ":" + skeyword + " " + contact; } else { queryStr = " " + operation + field + ":" + keyword + " " + contact; } } else if ((field == "" || field == "party") && keyword == "") { queryStr = ""; } var timeText = " ( "; if (timefieldtext != "-") { if (startTime > endTime) {// 调换位置时间的开始时间和结束时间 var tempTime = startTime; startTime = endTime; endTime = tempTime; } for (var i = 0; startTime <= endTime; i++) { // +caseNo:仿盛大发生 OR +caseNo:仿盛大发生 OR +caseNo:道德 timeText += " +caseNo:" + startTime + " OR"; startTime++; } timeText = timeText.substring(0, timeText.lastIndexOf("OR")); queryStr += timeText + " ) "; } if (keyword == "" && field == "party") {// 当事人的话,不考虑归档与否 queryStr = "+archive:" + archive + " AND" + queryStr + "@party:"; } else if (keyword != "" && field != "party") {// 案子的话需要考虑归档与否 queryStr = "+archive:" + archive + " AND +state:" + archivestate + " AND" + queryStr; } else if (keyword != "" && field == "party") {// 当事人的话,不考虑归档与否 queryStr = "+archive:" + archive + " AND" + queryStr; }else if (keyword == "" && field != "party") {// 案子的话需要考虑归档与否 queryStr = "+archive:" + archive + " AND +state:" + archivestate + " AND" + queryStr; } alert(queryStr); document.getElementById('queryString').value = (document .getElementById('queryString').value == undefined ? "" : document .getElementById('queryString').value) + queryStr; var archivetext = document.getElementById("archive").options[document .getElementById("archive").selectedIndex].text; var archivestatetext = document.getElementById("archivestate").options[document .getElementById("archivestate").selectedIndex].text; var fieldtext = document.getElementById("field").options[document .getElementById("field").selectedIndex].text; var operationtext = document.getElementById("operation").options[document .getElementById("operation").selectedIndex].text; var contacttext = document.getElementById("contact").options[document .getElementById("contact").selectedIndex].text; document.getElementById("archivetext").innerHTML = document .getElementById("archivetext").innerHTML + "<div>" + archivetext + "</div>"; document.getElementById("archivestatetext").innerHTML = document .getElementById("archivestatetext").innerHTML + "<div>" + archivestatetext + "</div>"; document.getElementById("timefieldtext").innerHTML = document .getElementById("timefieldtext").innerHTML + "<div>" + timefieldtext + "</div>"; document.getElementById("fieldtext").innerHTML = document .getElementById("fieldtext").innerHTML + "<div>" + fieldtext + "</div>"; document.getElementById("operationtext").innerHTML = document .getElementById("operationtext").innerHTML + "<div>" + operationtext + "</div>"; document.getElementById("keywordtext").innerHTML = document .getElementById("keywordtext").innerHTML + "<div>" + keyword + "</div>"; document.getElementById("contacttext").innerHTML = document .getElementById("contacttext").innerHTML + "<div>" + contacttext + "</div>"; var subbuttontext = "<img src='/images/button-.gif' width='14' style='cursor:pointer' height='14' οnclick=\"sub('" + queryStr + "','" + archivetext + "','" + archivestatetext + "','" + timefieldtext + "','" + fieldtext + "','" + operationtext + "','" + keyword + "','" + contacttext + "',this);\"/>"; document.getElementById("subbutton").innerHTML = document .getElementById("subbutton").innerHTML + "<div>" + subbuttontext + "</div>"; } function dealwith() { var items = document.getElementsByName("fields"); if (items.length) { for (var i = 0; i < items.length; i++) { if (items[i].checked) { items[i].checked = false; } else { items[i].checked = true; } } } } function search(alias) { var str = document.getElementById('queryString').value; if (str.length < 1) { alert("请添加搜索条件"); return false; } var partyStr = str.substring(str.lastIndexOf(" "), str.length); str = str.substring(0, str.lastIndexOf(" ")); if (str.indexOf("party:") != -1 || partyStr != " ") { alias = " AND +alias:Party "; document.getElementById('searchform').action = "/archiveReadIn/lawsuitArchiveSynthesizeSearch!searchParty.action"; } document.getElementById('queryString').value = str + alias; dealwith(); document.getElementById('searchform').submit(); } function sub(delStr, delarchivetext, delarchivestatetext, deltimeText, delfieldtext, deloperationtext, delkeywordtext, delcontacttext, obj) { var archivetext = document.getElementById("archivetext"); var archivestatetext = document.getElementById("archivestatetext"); var datefeild = document.getElementById("timefieldtext"); var fieldtext = document.getElementById("fieldtext"); var operationtext = document.getElementById("operationtext"); var keywordtext = document.getElementById("keywordtext"); var contacttext = document.getElementById("contacttext"); archivetext.innerHTML = deleteString(archivetext.innerHTML, delarchivetext); archivestatetext.innerHTML = deleteString(archivestatetext.innerHTML, delarchivestatetext); datefeild.innerHTML = deleteString(datefeild.innerHTML, deltimeText); fieldtext.innerHTML = deleteString(fieldtext.innerHTML, delfieldtext); operationtext.innerHTML = deleteString(operationtext.innerHTML, deloperationtext); keywordtext.innerHTML = deleteString(keywordtext.innerHTML, delkeywordtext); contacttext.innerHTML = deleteString(contacttext.innerHTML, delcontacttext); obj.style.display = "none"; var str = document.getElementById('queryString').value; str = deleteString(str, delStr); document.getElementById('queryString').value = str; } // 提取查找字符串前面所有的字符 function getFront(mainStr, searchStr) { foundOffset = mainStr.indexOf(searchStr); if (foundOffset == -1) { return null; } return mainStr.substring(0, foundOffset); } // 提取查找字符串后面的所有字符 function getEnd(mainStr, searchStr) { foundOffset = mainStr.indexOf(searchStr); if (foundOffset == -1) { return null; } return mainStr.substring(foundOffset + searchStr.length, mainStr.length); } // 在字符串 searchStr 前面插入字符串 insertStr function insertString(mainStr, searchStr, insertStr) { var front = getFront(mainStr, searchStr); var end = getEnd(mainStr, searchStr); if (front != null && end != null) { return front + insertStr + searchStr + end; } return null; } // 删除字符串 deleteStr function deleteString(mainStr, deleteStr) { return replaceString(mainStr, deleteStr, ""); } // 将字符串 searchStr 修改为 replaceStr function replaceString(mainStr, searchStr, replaceStr) { var front = getFront(mainStr, searchStr); var end = getEnd(mainStr, searchStr); if (front != null && end != null) { return front + replaceStr + end; } return null; }
最后形成的字符串:LawsuitArvhive 不含关键字:
16:22:37,220 INFO [com.lzjw.court.utils.SecurityConfig] 当前系统已经启用安全子系统
---------------------------------------------
queryString=+archive:penal AND +state:archived AND ( +caseNo:2008 OR +caseNo:2009 OR +caseNo:2010 ) AND +alias:LawsuitArchive
查找到的数目=3
含有关键字:
16:23:55,347 INFO [com.lzjw.court.utils.SecurityConfig] 当前系统已经启用安全子系统
---------------------------------------------
queryString=+archive:penal AND +state:archived AND +caseNo:案号 AND ( +caseNo:2008 OR +caseNo:2009 OR +caseNo:2010 ) AND +alias:LawsuitArchive
查找到的数目=1
当事人 party含有关键字:
16:24:49,231 INFO [com.lzjw.court.utils.SecurityConfig] 当前系统已经启用安全子系统
16:24:49,258 INFO [com.lzjw.court.common.service.impl.PartyManagerImpl] hits:3
16:24:49,258 INFO [com.lzjw.court.common.service.impl.PartyManagerImpl] queryString:+archive:penal AND +party:当事人 AND ( +caseNo:2008 OR +caseNo:2009 OR +caseNo:2010 ) AND +alias:Party
当事人不含关键字:
16:25:47,972 INFO [com.lzjw.court.utils.SecurityConfig] 当前系统已经启用安全子系统
16:25:47,985 INFO [com.lzjw.court.common.service.impl.PartyManagerImpl] hits:11
16:25:47,985 INFO [com.lzjw.court.common.service.impl.PartyManagerImpl] queryString:+archive:penal AND ( +caseNo:2008 OR +caseNo:2009 OR +caseNo:2010 ) AND +alias:Party
勉勉强强的解决了问题。贴出来如果各位仁兄有好的意见和建议的话,请不惜赐教!