File name
Commit message
Commit date
2023-07-03
File name
Commit message
Commit date
2023-07-03
File name
Commit message
Commit date
File name
Commit message
Commit date
2023-07-03
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;
}
}