@Override public boolean reload(String collectionName, int docNum) { if (collectionName == null) return false; CrescentCollectionHandler collectionHandler = SpringApplicationContext.getBean( "crescentCollectionHandler", CrescentCollectionHandler.class); CrescentCollection collection = collectionHandler.getCrescentCollections().getCrescentCollection(collectionName); if (collection == null) { logger.debug("doesn't Collection Info => {}", collectionName); return false; } List<String> fieldName = new ArrayList<String>(); List<String> flag = new ArrayList<String>(); List<String> norm = new ArrayList<String>(); List<String> value = new ArrayList<String>(); try { Directory directory = FSDirectory.open(new File(collection.getIndexingDirectory())); IndexReader reader = IndexReader.open(directory); Document document = null; try { document = reader.document(docNum); } catch (IllegalArgumentException e) { e.printStackTrace(); return false; } String fName = null; for (Fieldable field : document.getFields()) { fName = field.name(); fieldName.add(fName); flag.add(fieldFlag(field)); if (reader.hasNorms(fName)) { norm.add(String.valueOf(Similarity.decodeNorm(reader.norms(fName)[docNum]))); } else { norm.add("---"); } value.add(field.stringValue()); } } catch (IOException e) { e.printStackTrace(); return false; } result.put("collection", collectionName); result.put("docNum", docNum); result.put("fieldName", fieldName); result.put("flag", flag); result.put("norm", norm); result.put("value", value); return true; }
@Override public SearchResult search(CrescentSearchRequestWrapper csrw) throws IOException { SearchResult searchResult = new SearchResult(); int totalHitsCount = 0; String errorMessage = "SUCCESS"; int errorCode = 0; // 5page * 50 int numOfHits = csrw.getDefaultHitsPage() * csrw.getHitsForPage(); IndexSearcher indexSearcher = null; SearcherManager searcherManager = crescentSearcherManager.getSearcherManager(csrw.getCollectionName()); try { indexSearcher = searcherManager.acquire(); Query query = csrw.getQuery(); Filter filter = csrw.getFilter(); Sort sort = csrw.getSort(); logger.debug("query : {}", query); logger.debug("filter : {}", filter); logger.debug("sort : {}", sort); long startTime = System.currentTimeMillis(); TopDocs topDocs = null; if (sort == null) { topDocs = indexSearcher.search(query, filter, numOfHits); } else { topDocs = indexSearcher.search(query, filter, numOfHits, sort); } long endTime = System.currentTimeMillis(); // 전체 검색 건수 totalHitsCount = topDocs.totalHits; LogInfo logInfo = new LogInfo(); logInfo.setCollectionName(csrw.getCollectionName()); logInfo.setElaspedTimeMil(endTime - startTime); logInfo.setKeyword(csrw.getKeyword()); logInfo.setPageNum(csrw.getPageNum()); logInfo.setPcid(csrw.getPcId()); logInfo.setQuery(query); logInfo.setSort(csrw.getSort()); logInfo.setTotalCount(totalHitsCount); logInfo.setUserId(csrw.getUserId()); logInfo.setUserIp(csrw.getUserIp()); logInfo.setFilter(csrw.getFilter()); CrescentLogger.logging(logInfo); logger.debug("Total Hits Count : {} ", totalHitsCount); ScoreDoc[] hits = topDocs.scoreDocs; // 총 검색건수와 실제 보여줄 document의 offset (min ~ max)를 비교해서 작은 것을 가져옴 int endOffset = Math.min(totalHitsCount, csrw.getStartOffSet() + csrw.getHitsForPage()); if (endOffset > hits.length) { logger.debug("기본 설정된 검색건수보다 더 검색을 원하므로, 전체를 대상으로 검색합니다."); if (sort == null) { topDocs = indexSearcher.search(query, filter, totalHitsCount); } else { topDocs = indexSearcher.search(query, filter, totalHitsCount, sort); } hits = topDocs.scoreDocs; } int startOffset = csrw.getStartOffSet(); endOffset = Math.min(hits.length, startOffset + csrw.getHitsForPage()); // for(int i = startOffset; i < endOffset; i++) { // Document doc = indexSearcher.doc(hits[i].doc); // resultDocumentList.add(doc); // } logger.debug( "start offset : [{}], end offset : [{}], total : [{}], numOfHits :[{}]", new Object[] {csrw.getStartOffSet(), endOffset, totalHitsCount, numOfHits}); logger.debug("hits count : [{}]", hits.length); logger.debug( "startOffset + hitsPerPage : [{}]", csrw.getStartOffSet() + csrw.getHitsForPage()); if (totalHitsCount > 0) { List<Map<String, String>> resultList = new ArrayList<Map<String, String>>(); Map<String, Object> result = new HashMap<String, Object>(); CrescentFastVectorHighlighter highlighter = new CrescentFastVectorHighlighter(); CrescentCollectionHandler collectionHandler = SpringApplicationContext.getBean( "crescentCollectionHandler", CrescentCollectionHandler.class); CrescentCollection collection = collectionHandler .getCrescentCollections() .getCrescentCollection(csrw.getCollectionName()); // int docnum = 0; for (int i = startOffset; i < endOffset; i++) { Map<String, String> resultMap = new HashMap<String, String>(); for (CrescentCollectionField field : collection.getFields()) { String value = null; if (field.isStore() && !field.isNumeric()) { // 필드별 결과를 가져온다. value = highlighter.getBestFragment( indexSearcher.getIndexReader(), hits[i].doc, query, field.getName()); } if (value == null || value.length() == 0) { Document doc = indexSearcher.doc(hits[i].doc); value = doc.get(field.getName()); } resultMap.put(field.getName(), value); } resultList.add(resultMap); } result.put("total_count", totalHitsCount); result.put("result_list", resultList); result.put("error_code", errorCode); result.put("error_msg", errorMessage); logger.debug("result list {}", resultList); searchResult.setResultList(resultList); searchResult.setTotalHitsCount(totalHitsCount); searchResult.setSearchResult(result); } else { // 결과없음 Map<String, Object> result = new HashMap<String, Object>(); List<Map<String, String>> resultList = new ArrayList<Map<String, String>>(); result.put("total_count", totalHitsCount); result.put("result_list", resultList); result.put("error_code", errorCode); result.put("error_msg", errorMessage); logger.debug("result list {}", resultList); searchResult.setResultList(resultList); searchResult.setTotalHitsCount(0); searchResult.setSearchResult(result); } } catch (Exception e) { logger.error("error in CrescentDefaultDocSearcher : ", e); Map<String, Object> result = new HashMap<String, Object>(); List<Map<String, String>> resultList = new ArrayList<Map<String, String>>(); result.put("total_count", totalHitsCount); result.put("result_list", resultList); result.put("error_code", errorCode); result.put("error_msg", errorMessage); logger.error("검색 중 에러 발생함. {}", e); searchResult.setErrorCode(errorCode); searchResult.setErrorMsg(errorMessage); searchResult.setSearchResult(result); searchResult.setResultList(resultList); return searchResult; } finally { searcherManager.release(indexSearcher); indexSearcher = null; } return searchResult; }
@Override public boolean reload(String collectionName, String topRankingField) { if (collectionName == null) { return false; } CrescentCollectionHandler collectionHandler = SpringApplicationContext.getBean( "crescentCollectionHandler", CrescentCollectionHandler.class); CrescentCollection collection = collectionHandler.getCrescentCollections().getCrescentCollection(collectionName); if (collection == null) { logger.debug("doesn't Collection Info => {}", collectionName); init(View.Overview); return false; } if (topRankingField == null) { if (collection.getDefaultSearchFields().get(0) != null) { topRankingField = collection.getDefaultSearchFields().get(0).getName(); } else { logger.debug("doesn't defaultSearchField => {}", collectionName); init(View.Overview); return false; } } List<String> fieldName = new ArrayList<String>(); for (CrescentCollectionField field : collection.getFields()) fieldName.add(field.getName()); TopRankingQueue topRankingQueue = new TopRankingQueue(DEFAULT_TOPRANKING_TERM, new RankingTermComparator()); try { Directory directory = FSDirectory.open(new File(collection.getIndexingDirectory())); IndexReader reader = IndexReader.open(directory); TermEnum terms = reader.terms(); int termFreq = 0; int termCount = 0; Term beforeTerm = null; // init term count fieldTermCount.clear(); for (CrescentCollectionField field : collection.getFields()) fieldTermCount.put(field.getName(), 0); topRankingQueue.clear(); while (terms.next()) { Term currTerm = terms.term(); if (beforeTerm == null) { beforeTerm = currTerm; } if (beforeTerm.field() == currTerm.field()) { termCount++; } else { fieldTermCount.put(beforeTerm.field(), termCount); termCount = 1; beforeTerm = currTerm; } TermDocs termDocs = reader.termDocs(currTerm); while (termDocs.next()) { if (currTerm.field().equals(topRankingField)) { RankingTerm e = new RankingTerm(currTerm.text(), currTerm.field(), termDocs.freq()); topRankingQueue.add(e); } } termFreq++; } if (beforeTerm != null) fieldTermCount.put(beforeTerm.field(), termCount); terms.close(); result.put("numOfTerm", termFreq); result.put("numOfDoc", reader.numDocs()); result.put("hasDel", reader.hasDeletions()); result.put("isOptimize", reader.isOptimized()); result.put("indexVersion", reader.getVersion()); result.put("lastModify", new Date(IndexReader.lastModified(directory))); } catch (IOException e) { e.printStackTrace(); return false; } if (topRankingQueue.size() != 0) { topRankingTerms = topRankingQueue.toArray(); Arrays.sort(topRankingTerms); } result.put("collectionName", collectionName); result.put("indexName", collection.getIndexingDirectory()); result.put("numOfField", collection.getFields().size()); result.put("termCount", fieldTermCount); result.put("topRanking", topRankingTerms); result.put("fieldName", fieldName); return true; }