Elasticsearch 원본 분석 3 - Lucene 검색 인터페이스를 호출하는 단어 조회

9352 단어

Elasticsearch 원본 분석 3 – Lucene 검색 인터페이스를 호출하는 단어 조회

  • 소개
  • 조회 문법
  • 원본 분석

  • 소개


    단어 조회는 Elasticsearch의 간단한 조회입니다.이것은 주어진 필드에 이 단어가 포함된 문서만 일치하고 정확하고 분석되지 않은 단어입니다.단어 조회는 분석되지 않았기 때문에 색인 문서의 단어와 완전히 일치하는 단어를 제공해야 한다는 것을 기억하십시오.다중 단어 조회는 내용에 어떤 단어가 포함된 문서와 일치할 수 있도록 합니다.

    질의 문법


    예1: 검색 제목 필드에crime이라는 단어가 있는 문서는 색인을 만들 때 소문자로 바뀌고, 검색할 때도 소문자 {"query": {"term": {"title": "crime"}}}예2: tags 필드에 novel이나 book이 있는 모든 문서 {"query": {"terms": {"tags": ["novel", "book]}}}}}

    원본 분석

    '''(1)Elasticsearch code'''
    public class TermQueryParser implements QueryParser {
        public static final String NAME = "term";
        public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
            XContentParser parser = parseContext.parser();
    
            XContentParser.Token token = parser.nextToken();
            if (token != XContentParser.Token.FIELD_NAME) {
                throw new QueryParsingException(parseContext.index(), "[term] query malformed, no field");
            }
            String fieldName = parser.currentName();
    
            Object value = null;
            float boost = 1.0f;
            token = parser.nextToken();
            if (token == XContentParser.Token.START_OBJECT) {
                String currentFieldName = null;
                while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                    if (token == XContentParser.Token.FIELD_NAME) {
                        currentFieldName = parser.currentName();
                    } else {
                        if ("term".equals(currentFieldName)) {
                            value = parser.objectBytes();
                        } else if ("value".equals(currentFieldName)) {
                            value = parser.objectBytes();
                        } else if ("boost".equals(currentFieldName)) {
                            boost = parser.floatValue();
                        } else {
                            throw new QueryParsingException(parseContext.index(), "[term] query does not support [" + currentFieldName + "]");
                        }
                    }
                }
                parser.nextToken();
            } else {
                value = parser.text();
                // move to the next token
                parser.nextToken();
            }
    
            if (value == null) {
                throw new QueryParsingException(parseContext.index(), "No value specified for term query");
            }
    
            Query query = null;
            MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
            if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
                if (smartNameFieldMappers.explicitTypeInNameWithDocMapper()) {
                    String[] previousTypes = QueryParseContext.setTypesWithPrevious(new String[]{smartNameFieldMappers.docMapper().type()});
                    try {
                        query = smartNameFieldMappers.mapper().termQuery(value, parseContext);
                    } finally {
                        QueryParseContext.setTypes(previousTypes);
                    }
                } else {
                    query = smartNameFieldMappers.mapper().termQuery(value, parseContext);
                }
            }
            if (query == null) {
                ''' Lucene TermQuery (Term("title","crime")) '''
                query = new TermQuery(new Term(fieldName, BytesRefs.toBytesRef(value)));
            }
            query.setBoost(boost);
            return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext);
        }
     }
    '''(2)Lucene code'''
    
    public class TermQuery extends Query {
      private final Term term;
      ''' Weight , Term Weight'''
      public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
        final IndexReaderContext context = searcher.getTopReaderContext();
        final TermContext termState;
        if (perReaderTermState == null
            || perReaderTermState.topReaderContext != context) {
          // make TermQuery single-pass if we don't have a PRTS or if the context
          // differs!
          termState = TermContext.build(context, term);
        } else {
          // PRTS was pre-build for this IS
          termState = this.perReaderTermState;
        }
    
        return new TermWeight(searcher, needsScores, termState);
      }
      '''Weight '''
      final class TermWeight extends Weight {
         ''' Scorer , '''
         public Scorer scorer(LeafReaderContext context) throws IOException {
          assert termStates.topReaderContext == ReaderUtil.getTopLevelContext(context) : "The top-reader used to create Weight (" + termStates.topReaderContext + ") is not the same as the current reader's top-reader (" + ReaderUtil.getTopLevelContext(context);
          final TermsEnum termsEnum = getTermsEnum(context);
          if (termsEnum == null) {
            return null;
          }
          PostingsEnum docs = termsEnum.postings(null, needsScores ? PostingsEnum.FREQS : PostingsEnum.NONE);
          assert docs != null;
          return new TermScorer(this, docs, similarity.simScorer(stats, context));
        }
      }
    }
    
    

    좋은 웹페이지 즐겨찾기