File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package itn.let.solr.search.impl;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SpellCheckResponse.Suggestion;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.params.CommonParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.ModelMap;
import itn.let.solr.search.service.SearchService;
public class SearchServiceImpl implements InitializingBean, SearchService {
Logger log = LoggerFactory.getLogger(this.getClass());
@Value("${Globals.Solr.url}")
private String SERVER_URL;
private Set<String> introFieldSet;
private Set<String> policyFieldSet;
private Set<String> safetyFieldSet;
private Set<String> noticeFieldSet;
private Set<String> communityFieldSet;
private Set<String> infoFieldSet;
private Set<String> fileFieldSet;
@SuppressWarnings("unused")
private Set<String> boardFieldSet;
@SuppressWarnings("unused")
private Set<String> webpageFieldSet;
@SuppressWarnings("unused")
private Set<String> itn_BoardFieldSet;
@SuppressWarnings("unused")
private Set<String> itn_ContentFieldSet;
private Map<String, Set<String>> fieldMap = new HashMap<String, Set<String>>();
private final String REGEX = "^[1-9a-zA-Zㄱ-ㅎㅏ-ㅣ가-힣| *]+$";
private final String SPECIAL_REGEX = "[^ㄱ-ㅎ\uAC00-\uD7A3xfe0-9a-zA-Z\\s]";
private Pattern pattern = Pattern.compile(REGEX);
public SearchServiceImpl(){
}
@Override
public void afterPropertiesSet() throws Exception {
fieldMap.put(SOLR_CORE.INTRO.getValue(), introFieldSet);
fieldMap.put(SOLR_CORE.POLICY.getValue(), policyFieldSet);
fieldMap.put(SOLR_CORE.SAFETY.getValue(), safetyFieldSet);
fieldMap.put(SOLR_CORE.NOTICE.getValue(), noticeFieldSet);
fieldMap.put(SOLR_CORE.COMMUNITY.getValue(), communityFieldSet);
fieldMap.put(SOLR_CORE.INFO.getValue(), infoFieldSet);
/*fieldMap.put(SOLR_CORE.FILE.getValue(), fileFieldSet);
fieldMap.put(SOLR_CORE.WEBPAGE.getValue(), webpageFieldSet);
fieldMap.put(SOLR_CORE.BOARD.getValue(), boardFieldSet);
fieldMap.put(SOLR_CORE.ITN_BOARD.getValue(), itn_BoardFieldSet);
fieldMap.put(SOLR_CORE.ITN_CONTENT.getValue(), itn_ContentFieldSet);*/
}
@Override
public Set<String> suggest(Map<String, Object> commandMap) throws Exception {
String q = (String)commandMap.get("q");
if (StringUtils.isBlank(q)) {
return Collections.emptySet();
}
q = URLDecoder.decode(q, "UTF-8");
Set<String> resultList = new LinkedHashSet<String>();
SolrQuery query = new SolrQuery();
query.setParam(CommonParams.QT, "/suggest");
query.setQuery(q);
String serverUrl = SERVER_URL.endsWith("/") ? SERVER_URL : SERVER_URL + "/";
for(SOLR_CORE sc : SOLR_CORE.values()){
SolrClient client = null;
try {
client = new HttpSolrClient(serverUrl+sc.getValue());
QueryResponse rsp = client.query(query);
if (rsp != null) {
List<Suggestion> suggestions = rsp.getSpellCheckResponse().getSuggestions();
if( CollectionUtils.isNotEmpty(suggestions) ){
for(Suggestion s : suggestions){
resultList.addAll(s.getAlternatives());
}
}
}
} catch (SolrServerException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(client);
}
}
log.debug("{} - {}", serverUrl, resultList);
return resultList;
}
@Override
public void search(Map<String, Object> commandMap, ModelMap model) throws Exception {
String q = (String)commandMap.get("q");
if ( StringUtils.isBlank(q) ) {
q = (String)commandMap.get("q2");
}
if (StringUtils.isNotBlank(q)) {
Matcher matcher = pattern.matcher(q);
if( matcher.find() ) {
commandMap.put("srchwrd", q);
}
}
Map<String, List<Map<String, Object>>> resultMap = new HashMap<String, List<Map<String, Object>>>();
Map<String, Long> resultCntMap = new HashMap<String, Long>();
long totalCount = 0;
for (SOLR_CORE sc : SOLR_CORE.values()) {
resultCntMap.put(sc.getValue(), new Long(0));
resultMap.put(sc.getValue(), Collections.<Map<String, Object>>emptyList());
List<Map<String, Object>> resultList = getResultList(sc, fieldMap.get(sc.getValue()), commandMap);
long numFound = 0;
if ( !CollectionUtils.isEmpty(resultList) ) {
Map<String, Object> result = resultList.get(0);
numFound = NumberUtils.toLong(result.get("numFound").toString());
totalCount += numFound;
resultCntMap.put(sc.getValue(), numFound);
resultMap.put(sc.getValue(), resultList);
}
if ( sc.getValue().equals((String)commandMap.get("rangeView")) ) {
}
}
model.addAttribute("resultMap", resultMap);
model.addAttribute("resultCntMap", resultCntMap);
model.addAttribute("totalCount", totalCount);
}
private List<Map<String, Object>> getResultList(SOLR_CORE core, Set<String> fieldSet, Map<String, Object> commandMap){
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
String serverUrl = SERVER_URL.endsWith("/") ? SERVER_URL : SERVER_URL + "/";
HttpSolrClient client = null;
SolrQuery query = makeQuery(core, commandMap, fieldSet);
log.debug("{}{}", serverUrl, query);
try {
client = new HttpSolrClient(serverUrl+core.getValue());
client.setConnectionTimeout(1000);
QueryResponse rsp = client.query(query);
Iterator<SolrDocument> iter = rsp.getResults().iterator();
long numFound = rsp.getResults().getNumFound();
while (iter.hasNext()) {
Map<String, Object> resultMap = new HashMap<>();
SolrDocument resultDoc = iter.next();
for(String field : fieldSet){
resultMap.put(field, resultDoc.getFieldValue(field));
}
Object id = resultDoc.getFieldValue("id");
Map<String, Map<String, List<String>>> highlighting = rsp.getHighlighting();
if( highlighting.get(id.toString()) != null ){
Map<String, List<String>> highlightSnippetMap = highlighting.get(id);
String hlFl = StringUtils.defaultString((String)commandMap.get("hl.fl"), "text");
List<String> highlightSnippets = highlightSnippetMap.get(hlFl);
if( CollectionUtils.isNotEmpty(highlightSnippets) ){
resultMap.put("hl", highlightSnippets.get(0));
}
List<String> nttSjHl = highlightSnippetMap.get("nttSj");
if( CollectionUtils.isNotEmpty(nttSjHl) ){
resultMap.put("nttSjHl", nttSjHl.get(0));
}
}
resultMap.put("numFound", numFound);
resultList.add(resultMap);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(client);
}
return resultList;
}
private SolrQuery makeQuery(SOLR_CORE core, Map<String, Object> commandMap, Set<String> fieldSet){
SolrQuery query = new SolrQuery();
String q = StringUtils.defaultString((String)commandMap.get("q"));
q = q.replaceAll(SPECIAL_REGEX, "");
String re = (String)commandMap.get("re");
String sdate = (String)commandMap.get("sdate");
String edate = (String)commandMap.get("edate");
String date = (String)commandMap.get("date");
int pageIndex = 1;
String rangeView = (String)commandMap.get("rangeView");
if (core.getValue().equals(rangeView)) {
String pi = (String)commandMap.get("pageIndex");
if (StringUtils.isNotBlank(pi)) {
pageIndex = NumberUtils.toInt(pi, 1);
}
}
int pageUnit = 10;
int start = (pageIndex -1) * pageUnit;
query.setStart(start);
StringBuilder _q = new StringBuilder();
if( "Y".equals(re) ){
String prevQ = (String)commandMap.get("prevQ");
if( StringUtils.isNotBlank(q) && StringUtils.isNotBlank(prevQ) ){
_q.append(q).append(" AND ").append(prevQ);
}
else if( StringUtils.isNotBlank(prevQ) ){
_q.append(prevQ);
}
else if( StringUtils.isNotBlank(q) ){
_q.append(q);
}
else{
_q.append("*:*");
}
}
else{
if( !StringUtils.isNotBlank(q) ){
_q.append("*:*");
}
else{
_q.append(q);
}
}
if( !"*:*".equals(_q.toString()) ){
_q.insert(0, "*");
_q.append("*");
}
if (StringUtils.isNotBlank(sdate) && StringUtils.isNotBlank(edate)) {
query.addFilterQuery("registDt:["+sdate+" TO "+edate+"]");
}
if (StringUtils.isNotBlank(date)) {
Date today = new Date();
String e = DateFormatUtils.format(today, "yyyy-mm-dd");
String s = "";
if ("1d".equals(date)) {
s = DateFormatUtils.format(DateUtils.addDays(today, -1), "yyyy-mm-dd");
}
else if ("1w".equals(date)) {
s = DateFormatUtils.format(DateUtils.addDays(today, -7), "yyyy-mm-dd");
}
else if ("1m".equals(date)) {
s = DateFormatUtils.format(DateUtils.addMonths(today, -1), "yyyy-mm-dd");
}
else if ("3m".equals(date)) {
s = DateFormatUtils.format(DateUtils.addMonths(today, -3), "yyyy-mm-dd");
}
else if ("6m".equals(date)) {
s = DateFormatUtils.format(DateUtils.addMonths(today, -6), "yyyy-mm-dd");
}
query.addFilterQuery("registDt:["+s+" TO "+e+"]");
}
String categoryData = (String)commandMap.get("categoryData");
log.debug("categoryData : {}", categoryData);
if (categoryData != null) {
String[] data = StringUtils.split(categoryData, ",");
for (String c : data) {
query.addFilterQuery("category:" + c);
}
}
String hlFl = StringUtils.defaultString((String)commandMap.get("hl.fl"), "text");
String hlFragsize = StringUtils.defaultString((String)commandMap.get("hl.fragsize"), "140");
query.setQuery(_q.toString());
query.setHighlight(true).setHighlightSnippets(1);
query.setParam("hl.fl", hlFl, "nttSj");
query.setParam("hl.fragsize", hlFragsize);
Map<String, ORDER> m = getSortMap(commandMap, fieldSet);
if( m != null ) {
for (Map.Entry<String, ORDER> entry : m.entrySet()) {
query.addSort(entry.getKey(), entry.getValue());
}
}
return query;
}
private Map<String, ORDER> getSortMap(Map<String, Object> commandMap, Set<String> fieldSet) {
Map<String, ORDER> sortMap = new HashMap<String, ORDER>();
String s = (String)commandMap.get("s");
if( StringUtils.isNotBlank(s) ){
String[] data = StringUtils.split(s, "^");
for (String d : data) {
String[] sortField = StringUtils.split(d, "|");
if ( !"default".equals(sortField[0]) ) {
if (fieldSet != null && fieldSet.contains(sortField[0])) {
String field = sortField[0];
ORDER order = null;
if (sortField[1].equals("asc")) {
order = SolrQuery.ORDER.asc;
}
else {
order = SolrQuery.ORDER.desc;
}
sortMap.put(field, order);
}
}
}
}
return sortMap;
}
public Set<String> getFileFieldSet() {
return fileFieldSet;
}
public void setFileFieldSet(Set<String> fileFieldSet) {
this.fileFieldSet = fileFieldSet;
}
public void setBoardFieldSet(Set<String> boardFieldSet) {
this.boardFieldSet = boardFieldSet;
}
public void setWebpageFieldSet(Set<String> webpageFieldSet) {
this.webpageFieldSet = webpageFieldSet;
}
public void setItn_BoardFieldSet(Set<String> itn_BoardFieldSet) {
this.itn_BoardFieldSet = itn_BoardFieldSet;
}
public void setItn_ContentFieldSet(Set<String> itn_ContentFieldSet) {
this.itn_ContentFieldSet = itn_ContentFieldSet;
}
public Set<String> getIntroFieldSet() {
return introFieldSet;
}
public void setIntroFieldSet(Set<String> introFieldSet) {
this.introFieldSet = introFieldSet;
}
public Set<String> getPolicyFieldSet() {
return policyFieldSet;
}
public void setPolicyFieldSet(Set<String> policyFieldSet) {
this.policyFieldSet = policyFieldSet;
}
public Set<String> getSafetyFieldSet() {
return safetyFieldSet;
}
public void setSafetyFieldSet(Set<String> safetyFieldSet) {
this.safetyFieldSet = safetyFieldSet;
}
public Set<String> getNoticeFieldSet() {
return noticeFieldSet;
}
public void setNoticeFieldSet(Set<String> noticeFieldSet) {
this.noticeFieldSet = noticeFieldSet;
}
public Set<String> getCommunityFieldSet() {
return communityFieldSet;
}
public void setCommunityFieldSet(Set<String> communityFieldSet) {
this.communityFieldSet = communityFieldSet;
}
public Set<String> getInfoFieldSet() {
return infoFieldSet;
}
public void setInfoFieldSet(Set<String> infoFieldSet) {
this.infoFieldSet = infoFieldSet;
}
}