package org.fastcatsearch.ir.search.clause; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.*; import org.apache.lucene.analysis.tokenattributes.FeatureAttribute.FeatureType; import org.apache.lucene.util.CharsRef; import org.fastcatsearch.ir.io.CharVector; import org.fastcatsearch.ir.io.CharVectorTokenizer; import org.fastcatsearch.ir.query.HighlightInfo; import org.fastcatsearch.ir.query.RankInfo; import org.fastcatsearch.ir.query.Term; import org.fastcatsearch.ir.query.Term.Option; import org.fastcatsearch.ir.search.PostingReader; import org.fastcatsearch.ir.search.SearchIndexReader; import org.fastcatsearch.ir.search.method.NormalSearchMethod; import org.fastcatsearch.ir.search.method.SearchMethod; import org.fastcatsearch.ir.settings.IndexRefSetting; import org.fastcatsearch.ir.settings.IndexSetting; import java.io.IOException; import java.io.PrintStream; import java.io.Writer; @Deprecated public class PhraseClauseOld extends OperatedClause { private MultiTermOperatedClause operatedClause; public PhraseClauseOld(SearchIndexReader searchIndexReader, Term term, HighlightInfo highlightInfo) { super(searchIndexReader.indexId()); String indexId = searchIndexReader.indexId(); String termString = term.termString(); int weight = term.weight(); Option option = term.option(); CharVector fullTerm = new CharVector(termString); Analyzer analyzer = searchIndexReader.getQueryAnalyzerFromPool(); IndexSetting indexSetting = searchIndexReader.indexSetting(); if (highlightInfo != null) { String queryAnalyzerId = indexSetting.getQueryAnalyzer(); for (IndexRefSetting refSetting : indexSetting.getFieldList()) { highlightInfo.add(refSetting.getRef(), refSetting.getIndexAnalyzer(), queryAnalyzerId, term.termString(),term.option().value()); } } operatedClause = new MultiTermOperatedClause(indexId, searchIndexReader.indexFieldOption().isStorePosition()); try { CharVectorTokenizer charVectorTokenizer = new CharVectorTokenizer(fullTerm); CharTermAttribute termAttribute = null; CharsRefTermAttribute refTermAttribute = null; PositionIncrementAttribute positionAttribute = null; SynonymAttribute synonymAttribute = null; StopwordAttribute stopwordAttribute = null; FeatureAttribute featureAttribute = null; int positionOffset = 0; // 어절로 분리. while (charVectorTokenizer.hasNext()) { CharVector eojeol = charVectorTokenizer.next(); TokenStream tokenStream = analyzer.tokenStream(indexId, eojeol.getReader()); tokenStream.reset(); if (tokenStream.hasAttribute(CharsRefTermAttribute.class)) { refTermAttribute = tokenStream.getAttribute(CharsRefTermAttribute.class); } if (tokenStream.hasAttribute(CharTermAttribute.class)) { termAttribute = tokenStream.getAttribute(CharTermAttribute.class); } if (tokenStream.hasAttribute(PositionIncrementAttribute.class)) { positionAttribute = tokenStream.getAttribute(PositionIncrementAttribute.class); } CharTermAttribute charTermAttribute = tokenStream.getAttribute(CharTermAttribute.class); if (tokenStream.hasAttribute(SynonymAttribute.class)) { synonymAttribute = tokenStream.getAttribute(SynonymAttribute.class); } if (tokenStream.hasAttribute(StopwordAttribute.class)) { stopwordAttribute = tokenStream.getAttribute(StopwordAttribute.class); } if (tokenStream.hasAttribute(FeatureAttribute.class)) { featureAttribute = tokenStream.getAttribute(FeatureAttribute.class); } // PosTagAttribute tagAttribute = // tokenStream.getAttribute(PosTagAttribute.class); FeatureType prevType = null; CharVector token = null; while (tokenStream.incrementToken()) { if (refTermAttribute != null) { CharsRef charRef = refTermAttribute.charsRef(); if (charRef != null) { char[] buffer = new char[charRef.length()]; System.arraycopy(charRef.chars, charRef.offset, buffer, 0, charRef.length); token = new CharVector(buffer, 0, buffer.length, indexSetting.isIgnoreCase()); } else if (termAttribute != null && termAttribute.buffer() != null) { token = new CharVector(termAttribute.buffer(), indexSetting.isIgnoreCase()); } } else { token = new CharVector(charTermAttribute.buffer(), 0, charTermAttribute.length(), indexSetting.isIgnoreCase()); } // logger.debug("token = {}", token); // token.toUpperCase(); // // stopword // if (option.useStopword() && stopwordAttribute != null && stopwordAttribute.isStopword()) { logger.debug("stopword : {}", token); continue; } FeatureType featureType = null; if (featureAttribute != null) { featureType = featureAttribute.type(); if (featureType == FeatureType.APPEND) { if (prevType != null && (prevType == FeatureType.MAIN || prevType == FeatureType.APPEND)) { // 이전 타입이 main 또는 계속해서 append이면, 부가점수를 올려준다. // TODO } else { // 버린다. 즉, 검색시 무시된다. } } else { // main 결과 셋으로 사용. // TODO } prevType = featureType; } int queryPosition = 0; if (positionAttribute != null) { int position = positionAttribute.getPositionIncrement(); queryPosition = positionOffset + position; // positionOffset = position + 2; // 다음 position은 +2 부터 할당한다. 공백도 1만큼 차지. } logger.debug("PHRASE TERM {} >> [{}] [{}, {}] ", token, featureType, positionAttribute.getPositionIncrement(), queryPosition); SearchMethod searchMethod = searchIndexReader.createSearchMethod(new NormalSearchMethod()); PostingReader postingReader = searchMethod.search(indexId, token, queryPosition, weight); // OperatedClause clause = new TermOperatedClause(postingDocs, weight); // OperatedClause clause = new TermOperatedClause(postingReader); operatedClause.addTerm(postingReader); // if (operatedClause == null) { // operatedClause = clause; // } else { // operatedClause = new AndOperatedClause(operatedClause, clause); // } } } } catch (IOException e) { logger.error("", e); } finally { searchIndexReader.releaseQueryAnalyzerToPool(analyzer); } } @Override protected boolean nextDoc(RankInfo docInfo) { if (operatedClause == null) { return false; } return operatedClause.next(docInfo); } @Override public void close() { if(operatedClause != null){ operatedClause.close(); } } @Override public void printTrace(Writer writer, int indent, int depth) throws IOException { } @Override protected void initClause(boolean explain) { operatedClause.init(explanation != null ? explanation.createSubExplanation() : null); } // @Override // protected void initExplanation() { // if(operatedClause != null) { // operatedClause.setExplanation(explanation.createSub1()); // } // } }