public static Filter newFilter(
      QueryParseContext parseContext, String fieldPattern, String filterName) {
    final FieldMappers fieldNamesMappers =
        parseContext.mapperService().indexName(FieldNamesFieldMapper.NAME);
    final FieldNamesFieldMapper fieldNamesMapper =
        fieldNamesMappers == null ? null : (FieldNamesFieldMapper) fieldNamesMappers.mapper();

    MapperService.SmartNameObjectMapper smartNameObjectMapper =
        parseContext.smartObjectMapper(fieldPattern);
    if (smartNameObjectMapper != null && smartNameObjectMapper.hasMapper()) {
      // automatic make the object mapper pattern
      fieldPattern = fieldPattern + ".*";
    }

    List<String> fields = parseContext.simpleMatchToIndexNames(fieldPattern);
    if (fields.isEmpty()) {
      // no fields exists, so we should not match anything
      return Queries.MATCH_NO_FILTER;
    }
    MapperService.SmartNameFieldMappers nonNullFieldMappers = null;

    XBooleanFilter boolFilter = new XBooleanFilter();
    for (String field : fields) {
      MapperService.SmartNameFieldMappers smartNameFieldMappers =
          parseContext.smartFieldMappers(field);
      if (smartNameFieldMappers != null) {
        nonNullFieldMappers = smartNameFieldMappers;
      }
      Filter filter = null;
      if (fieldNamesMapper != null && fieldNamesMapper.enabled()) {
        final String f;
        if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
          f = smartNameFieldMappers.mapper().names().indexName();
        } else {
          f = field;
        }
        filter = fieldNamesMapper.termFilter(f, parseContext);
      }
      // if _field_names are not indexed, we need to go the slow way
      if (filter == null && smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
        filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true, parseContext);
      }
      if (filter == null) {
        filter = new TermRangeFilter(field, null, null, true, true);
      }
      boolFilter.add(filter, BooleanClause.Occur.SHOULD);
    }

    // we always cache this one, really does not change... (exists)
    // its ok to cache under the fieldName cacheKey, since its per segment and the mapping applies
    // to this data on this segment...
    Filter filter =
        parseContext.cacheFilter(boolFilter, new CacheKeyFilter.Key("$exists$" + fieldPattern));

    filter = wrapSmartNameFilter(filter, nonNullFieldMappers, parseContext);
    if (filterName != null) {
      parseContext.addNamedFilter(filterName, filter);
    }
    return filter;
  }
 @Override
 public PostingsFormat getPostingsFormatForField(String field) {
   final FieldMappers indexName = mapperService.indexName(field);
   if (indexName == null) {
     logger.warn("no index mapper found for field: [{}] returning default postings format", field);
     return defaultPostingFormat;
   }
   PostingsFormatProvider postingsFormat = indexName.mapper().postingsFormatProvider();
   return postingsFormat != null ? postingsFormat.get() : defaultPostingFormat;
 }
 @Override
 public DocValuesFormat getDocValuesFormatForField(String field) {
   final FieldMappers indexName = mapperService.indexName(field);
   if (indexName == null) {
     logger.warn(
         "no index mapper found for field: [{}] returning default doc values format", field);
     return defaultDocValuesFormat;
   }
   DocValuesFormatProvider docValuesFormat = indexName.mapper().docValuesFormatProvider();
   return docValuesFormat != null ? docValuesFormat.get() : defaultDocValuesFormat;
 }
 public void postProcess(MapperService mapperService) {
   if (uid != null) {
     DocumentMapper documentMapper = mapperService.documentMapper(uid.type());
     if (documentMapper != null) {
       // we can derive the exact type for the mapping
       postProcess(documentMapper);
       return;
     }
   }
   // can't derive exact mapping type
   for (Map.Entry<String, List<Object>> entry : fields().entrySet()) {
     FieldMappers fieldMappers = mapperService.indexName(entry.getKey());
     if (fieldMappers == null) {
       continue;
     }
     List<Object> fieldValues = entry.getValue();
     for (int i = 0; i < fieldValues.size(); i++) {
       fieldValues.set(i, fieldMappers.mapper().valueForSearch(fieldValues.get(i)));
     }
   }
 }
  private FieldSelector buildFieldSelectors(DocumentMapper docMapper, String... fields) {
    if (fields == null) {
      return docMapper.sourceMapper().fieldSelector();
    }

    // don't load anything
    if (fields.length == 0) {
      return null;
    }

    FieldMappersFieldSelector fieldSelector = null;
    for (String fieldName : fields) {
      FieldMappers x = docMapper.mappers().smartName(fieldName);
      if (x != null && x.mapper().stored()) {
        if (fieldSelector == null) {
          fieldSelector = new FieldMappersFieldSelector();
        }
        fieldSelector.add(x);
      }
    }

    return fieldSelector;
  }
예제 #6
0
  @Override
  public void execute(SearchContext context) {
    FieldsVisitor fieldsVisitor;
    Set<String> fieldNames = null;
    List<String> extractFieldNames = null;

    boolean loadAllStored = false;
    if (!context.hasFieldNames()) {
      // no fields specified, default to return source if no explicit indication
      if (!context.hasScriptFields() && !context.hasFetchSourceContext()) {
        context.fetchSourceContext(new FetchSourceContext(true));
      }
      fieldsVisitor =
          context.sourceRequested() ? new UidAndSourceFieldsVisitor() : new JustUidFieldsVisitor();
    } else if (context.fieldNames().isEmpty()) {
      if (context.sourceRequested()) {
        fieldsVisitor = new UidAndSourceFieldsVisitor();
      } else {
        fieldsVisitor = new JustUidFieldsVisitor();
      }
    } else {
      for (String fieldName : context.fieldNames()) {
        if (fieldName.equals("*")) {
          loadAllStored = true;
          continue;
        }
        if (fieldName.equals(SourceFieldMapper.NAME)) {
          if (context.hasFetchSourceContext()) {
            context.fetchSourceContext().fetchSource(true);
          } else {
            context.fetchSourceContext(new FetchSourceContext(true));
          }
          continue;
        }
        FieldMappers x = context.smartNameFieldMappers(fieldName);
        if (x == null) {
          // Only fail if we know it is a object field, missing paths / fields shouldn't fail.
          if (context.smartNameObjectMapper(fieldName) != null) {
            throw new IllegalArgumentException("field [" + fieldName + "] isn't a leaf field");
          }
        } else if (x.mapper().fieldType().stored()) {
          if (fieldNames == null) {
            fieldNames = new HashSet<>();
          }
          fieldNames.add(x.mapper().names().indexName());
        } else {
          if (extractFieldNames == null) {
            extractFieldNames = newArrayList();
          }
          extractFieldNames.add(fieldName);
        }
      }
      if (loadAllStored) {
        fieldsVisitor = new AllFieldsVisitor(); // load everything, including _source
      } else if (fieldNames != null) {
        boolean loadSource = extractFieldNames != null || context.sourceRequested();
        fieldsVisitor = new CustomFieldsVisitor(fieldNames, loadSource);
      } else if (extractFieldNames != null || context.sourceRequested()) {
        fieldsVisitor = new UidAndSourceFieldsVisitor();
      } else {
        fieldsVisitor = new JustUidFieldsVisitor();
      }
    }

    InternalSearchHit[] hits = new InternalSearchHit[context.docIdsToLoadSize()];
    FetchSubPhase.HitContext hitContext = new FetchSubPhase.HitContext();
    for (int index = 0; index < context.docIdsToLoadSize(); index++) {
      int docId = context.docIdsToLoad()[context.docIdsToLoadFrom() + index];
      int readerIndex = ReaderUtil.subIndex(docId, context.searcher().getIndexReader().leaves());
      LeafReaderContext subReaderContext =
          context.searcher().getIndexReader().leaves().get(readerIndex);
      int subDocId = docId - subReaderContext.docBase;

      final InternalSearchHit searchHit;
      try {
        int rootDocId = findRootDocumentIfNested(context, subReaderContext, subDocId);
        if (rootDocId != -1) {
          searchHit =
              createNestedSearchHit(
                  context,
                  docId,
                  subDocId,
                  rootDocId,
                  extractFieldNames,
                  loadAllStored,
                  fieldNames,
                  subReaderContext);
        } else {
          searchHit =
              createSearchHit(
                  context, fieldsVisitor, docId, subDocId, extractFieldNames, subReaderContext);
        }
      } catch (IOException e) {
        throw ExceptionsHelper.convertToElastic(e);
      }

      hits[index] = searchHit;
      hitContext.reset(searchHit, subReaderContext, subDocId, context.searcher());
      for (FetchSubPhase fetchSubPhase : fetchSubPhases) {
        if (fetchSubPhase.hitExecutionNeeded(context)) {
          fetchSubPhase.hitExecute(context, hitContext);
        }
      }
    }

    for (FetchSubPhase fetchSubPhase : fetchSubPhases) {
      if (fetchSubPhase.hitsExecutionNeeded(context)) {
        fetchSubPhase.hitsExecute(context, hits);
      }
    }

    context
        .fetchResult()
        .hits(
            new InternalSearchHits(
                hits,
                context.queryResult().topDocs().totalHits,
                context.queryResult().topDocs().getMaxScore()));
  }
  @Override
  protected GetResponse shardOperation(GetRequest request, int shardId)
      throws ElasticSearchException {
    IndexService indexService = indicesService.indexServiceSafe(request.index());
    BloomCache bloomCache = indexService.cache().bloomCache();
    IndexShard indexShard = indexService.shardSafe(shardId);

    DocumentMapper docMapper = indexService.mapperService().documentMapper(request.type());
    if (docMapper == null) {
      throw new TypeMissingException(new Index(request.index()), request.type());
    }

    if (request.refresh()) {
      indexShard.refresh(new Engine.Refresh(false));
    }

    Engine.Searcher searcher = indexShard.searcher();
    boolean exists = false;
    byte[] source = null;
    Map<String, GetField> fields = null;
    long version = -1;
    try {
      UidField.DocIdAndVersion docIdAndVersion =
          loadCurrentVersionFromIndex(
              bloomCache, searcher, docMapper.uidMapper().term(request.type(), request.id()));
      if (docIdAndVersion != null && docIdAndVersion.docId != Lucene.NO_DOC) {
        if (docIdAndVersion.version > 0) {
          version = docIdAndVersion.version;
        }
        exists = true;
        FieldSelector fieldSelector = buildFieldSelectors(docMapper, request.fields());
        if (fieldSelector != null) {
          Document doc = docIdAndVersion.reader.document(docIdAndVersion.docId, fieldSelector);
          source = extractSource(doc, docMapper);

          for (Object oField : doc.getFields()) {
            Fieldable field = (Fieldable) oField;
            String name = field.name();
            Object value = null;
            FieldMappers fieldMappers = docMapper.mappers().indexName(field.name());
            if (fieldMappers != null) {
              FieldMapper mapper = fieldMappers.mapper();
              if (mapper != null) {
                name = mapper.names().fullName();
                value = mapper.valueForSearch(field);
              }
            }
            if (value == null) {
              if (field.isBinary()) {
                value = field.getBinaryValue();
              } else {
                value = field.stringValue();
              }
            }

            if (fields == null) {
              fields = newHashMapWithExpectedSize(2);
            }

            GetField getField = fields.get(name);
            if (getField == null) {
              getField = new GetField(name, new ArrayList<Object>(2));
              fields.put(name, getField);
            }
            getField.values().add(value);
          }
        }

        // now, go and do the script thingy if needed
        if (request.fields() != null && request.fields().length > 0) {
          SearchLookup searchLookup = null;
          for (String field : request.fields()) {
            String script = null;
            if (field.contains("_source.") || field.contains("doc[")) {
              script = field;
            } else {
              FieldMappers x = docMapper.mappers().smartName(field);
              if (x != null && !x.mapper().stored()) {
                script = "_source." + x.mapper().names().fullName();
              }
            }
            if (script != null) {
              if (searchLookup == null) {
                searchLookup =
                    new SearchLookup(
                        indexService.mapperService(), indexService.cache().fieldData());
              }
              SearchScript searchScript = scriptService.search(searchLookup, "mvel", script, null);
              searchScript.setNextReader(docIdAndVersion.reader);
              searchScript.setNextDocId(docIdAndVersion.docId);

              try {
                Object value = searchScript.run();
                if (fields == null) {
                  fields = newHashMapWithExpectedSize(2);
                }
                GetField getField = fields.get(field);
                if (getField == null) {
                  getField = new GetField(field, new ArrayList<Object>(2));
                  fields.put(field, getField);
                }
                getField.values().add(value);
              } catch (RuntimeException e) {
                if (logger.isTraceEnabled()) {
                  logger.trace("failed to execute get request script field [{}]", e, script);
                }
                // ignore
              }
            }
          }
        }
      }
    } catch (IOException e) {
      throw new ElasticSearchException(
          "Failed to get type [" + request.type() + "] and id [" + request.id() + "]", e);
    } finally {
      searcher.release();
    }
    return new GetResponse(
        request.index(), request.type(), request.id(), version, exists, source, fields);
  }
 public void testDynamicMappingOnEmptyString() throws Exception {
   IndexService service = createIndex("test");
   client().prepareIndex("test", "type").setSource("empty_field", "").get();
   FieldMappers mappers = service.mapperService().indexName("empty_field");
   assertTrue(mappers != null && mappers.isEmpty() == false);
 }