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; }
@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); }