public SmartNameFieldMappers smartName(String smartName, @Nullable String[] types) { if (types == null || types.length == 0) { return smartName(smartName); } if (types.length == 1 && types[0].equals("_all")) { return smartName(smartName); } for (String type : types) { DocumentMapper documentMapper = mappers.get(type); // we found a mapper if (documentMapper != null) { // see if we find a field for it FieldMappers mappers = documentMapper.mappers().smartName(smartName); if (mappers != null) { return new SmartNameFieldMappers(this, mappers, documentMapper, false); } } } // did not find explicit field in the type provided, see if its prefixed with type int dotIndex = smartName.indexOf('.'); if (dotIndex != -1) { String possibleType = smartName.substring(0, dotIndex); DocumentMapper possibleDocMapper = mappers.get(possibleType); if (possibleDocMapper != null) { String possibleName = smartName.substring(dotIndex + 1); FieldMappers mappers = possibleDocMapper.mappers().smartName(possibleName); if (mappers != null) { return new SmartNameFieldMappers(this, mappers, possibleDocMapper, true); } } } // we did not find the field mapping in any of the types, so don't go and try to find // it in other types... return null; }
/** * Returns smart field mappers based on a smart name. A smart name is one that can optioannly be * prefixed with a type (and then a '.'). If it is, then the {@link * MapperService.SmartNameFieldMappers} will have the doc mapper set. * * <p> * * <p>It also (without the optional type prefix) try and find the {@link FieldMappers} for the * specific name. It will first try to find it based on the full name (with the dots if its a * compound name). If it is not found, will try and find it based on the indexName (which can be * controlled in the mapping), and last, will try it based no the name itself. * * <p> * * <p>If nothing is found, returns null. */ public SmartNameFieldMappers smartName(String smartName) { int dotIndex = smartName.indexOf('.'); if (dotIndex != -1) { String possibleType = smartName.substring(0, dotIndex); DocumentMapper possibleDocMapper = mappers.get(possibleType); if (possibleDocMapper != null) { String possibleName = smartName.substring(dotIndex + 1); FieldMappers mappers = possibleDocMapper.mappers().smartName(possibleName); if (mappers != null) { return new SmartNameFieldMappers(this, mappers, possibleDocMapper, true); } } } FieldMappers fieldMappers = fullName(smartName); if (fieldMappers != null) { return new SmartNameFieldMappers(this, fieldMappers, null, false); } fieldMappers = indexName(smartName); if (fieldMappers != null) { return new SmartNameFieldMappers(this, fieldMappers, null, false); } fieldMappers = name(smartName); if (fieldMappers != null) { return new SmartNameFieldMappers(this, fieldMappers, null, false); } return null; }
@Override protected Analyzer getWrappedAnalyzer(String fieldName) { int dotIndex = fieldName.indexOf('.'); if (dotIndex != -1) { String possibleType = fieldName.substring(0, dotIndex); DocumentMapper possibleDocMapper = mappers.get(possibleType); if (possibleDocMapper != null) { return possibleDocMapper.mappers().searchQuoteAnalyzer(); } } FieldMappers mappers = fieldMappers.fullName(fieldName); if (mappers != null && mappers.mapper() != null && mappers.mapper().searchQuoteAnalyzer() != null) { return mappers.mapper().searchQuoteAnalyzer(); } mappers = fieldMappers.indexName(fieldName); if (mappers != null && mappers.mapper() != null && mappers.mapper().searchQuoteAnalyzer() != null) { return mappers.mapper().searchQuoteAnalyzer(); } return defaultAnalyzer; }
public SmartNameObjectMapper smartNameObjectMapper(String smartName, @Nullable String[] types) { if (types == null || types.length == 0) { return smartNameObjectMapper(smartName); } if (types.length == 1 && types[0].equals("_all")) { return smartNameObjectMapper(smartName); } for (String type : types) { DocumentMapper possibleDocMapper = mappers.get(type); if (possibleDocMapper != null) { ObjectMapper mapper = possibleDocMapper.objectMappers().get(smartName); if (mapper != null) { return new SmartNameObjectMapper(mapper, possibleDocMapper); } } } // did not find one, see if its prefixed by type int dotIndex = smartName.indexOf('.'); if (dotIndex != -1) { String possibleType = smartName.substring(0, dotIndex); DocumentMapper possibleDocMapper = mappers.get(possibleType); if (possibleDocMapper != null) { String possiblePath = smartName.substring(dotIndex + 1); ObjectMapper mapper = possibleDocMapper.objectMappers().get(possiblePath); if (mapper != null) { return new SmartNameObjectMapper(mapper, possibleDocMapper); } } } // did not explicitly find one under the types provided, or prefixed by type... return null; }
public Analyzer searchQuoteAnalyzer() { if (hasMapper()) { Analyzer analyzer = mapper().searchQuoteAnalyzer(); if (analyzer != null) { return analyzer; } } if (docMapper != null && docMapper.searchQuotedAnalyzer() != null) { return docMapper.searchQuotedAnalyzer(); } return mapperService.searchQuoteAnalyzer(); }
public void remove(String type) { synchronized (typeMutex) { DocumentMapper docMapper = mappers.get(type); if (docMapper == null) { return; } docMapper.close(); mappers = newMapBuilder(mappers).remove(type).map(); removeObjectAndFieldMappers(docMapper); for (DocumentTypeListener typeListener : typeListeners) { typeListener.removed(type); } } }
public synchronized MergeResult merge(DocumentMapper mergeWith, MergeFlags mergeFlags) { MergeContext mergeContext = new MergeContext(this, mergeFlags); rootObjectMapper.merge(mergeWith.rootObjectMapper, mergeContext); for (Map.Entry<Class<? extends RootMapper>, RootMapper> entry : rootMappers.entrySet()) { // root mappers included in root object will get merge in the rootObjectMapper if (entry.getValue().includeInObject()) { continue; } RootMapper mergeWithRootMapper = mergeWith.rootMappers.get(entry.getKey()); if (mergeWithRootMapper != null) { entry.getValue().merge(mergeWithRootMapper, mergeContext); } } if (!mergeFlags.simulate()) { if (!mergeContext.newFieldMappers().mappers.isEmpty()) { addFieldMappers(mergeContext.newFieldMappers().mappers); } if (!mergeContext.newObjectMappers().mappers.isEmpty()) { addObjectMappers(mergeContext.newObjectMappers().mappers); } // let the merge with attributes to override the attributes meta = mergeWith.meta(); // update the source of the merged one refreshSource(); } return new MergeResult(mergeContext.buildConflicts()); }
/** * Returns all the fields that match the given pattern. If the pattern is prefixed with a type * then the fields will be returned with a type prefix. */ public Set<String> simpleMatchToIndexNames(String pattern) { if (!Regex.isSimpleMatchPattern(pattern)) { return ImmutableSet.of(pattern); } int dotIndex = pattern.indexOf('.'); if (dotIndex != -1) { String possibleType = pattern.substring(0, dotIndex); DocumentMapper possibleDocMapper = mappers.get(possibleType); if (possibleDocMapper != null) { Set<String> typedFields = Sets.newHashSet(); for (String indexName : possibleDocMapper.mappers().simpleMatchToIndexNames(pattern)) { typedFields.add(possibleType + "." + indexName); } return typedFields; } } return fieldMappers.simpleMatchToIndexNames(pattern); }
public SmartNameObjectMapper smartNameObjectMapper(String smartName) { int dotIndex = smartName.indexOf('.'); if (dotIndex != -1) { String possibleType = smartName.substring(0, dotIndex); DocumentMapper possibleDocMapper = mappers.get(possibleType); if (possibleDocMapper != null) { String possiblePath = smartName.substring(dotIndex + 1); ObjectMapper mapper = possibleDocMapper.objectMappers().get(possiblePath); if (mapper != null) { return new SmartNameObjectMapper(mapper, possibleDocMapper); } } } ObjectMappers mappers = objectMapper(smartName); if (mappers != null) { return new SmartNameObjectMapper(mappers.mapper(), null); } return null; }
/** * Returns all the fields that match the given pattern, with an optional narrowing based on a list * of types. */ public Set<String> simpleMatchToIndexNames(String pattern, @Nullable String[] types) { if (types == null || types.length == 0) { return simpleMatchToIndexNames(pattern); } if (types.length == 1 && types[0].equals("_all")) { return simpleMatchToIndexNames(pattern); } if (!Regex.isSimpleMatchPattern(pattern)) { return ImmutableSet.of(pattern); } Set<String> fields = Sets.newHashSet(); for (String type : types) { DocumentMapper possibleDocMapper = mappers.get(type); if (possibleDocMapper != null) { for (String indexName : possibleDocMapper.mappers().simpleMatchToIndexNames(pattern)) { fields.add(indexName); } } } return fields; }
private void removeObjectAndFieldMappers(DocumentMapper docMapper) { synchronized (mappersMutex) { fieldMappers.removeMappers(docMapper.mappers()); ImmutableOpenMap.Builder<String, ObjectMappers> fullPathObjectMappers = ImmutableOpenMap.builder(this.fullPathObjectMappers); for (ObjectMapper mapper : docMapper.objectMappers().values()) { ObjectMappers mappers = fullPathObjectMappers.get(mapper.fullPath()); if (mappers != null) { mappers = mappers.remove(mapper); if (mappers.isEmpty()) { fullPathObjectMappers.remove(mapper.fullPath()); } else { fullPathObjectMappers.put(mapper.fullPath(), mappers); } } } this.fullPathObjectMappers = fullPathObjectMappers.build(); } }
/** Same as {@link #smartName(String)}, except it returns just the field mappers. */ public FieldMappers smartNameFieldMappers(String smartName) { int dotIndex = smartName.indexOf('.'); if (dotIndex != -1) { String possibleType = smartName.substring(0, dotIndex); DocumentMapper possibleDocMapper = mappers.get(possibleType); if (possibleDocMapper != null) { String possibleName = smartName.substring(dotIndex + 1); FieldMappers mappers = possibleDocMapper.mappers().smartName(possibleName); if (mappers != null) { return mappers; } } } FieldMappers mappers = fullName(smartName); if (mappers != null) { return mappers; } mappers = indexName(smartName); if (mappers != null) { return mappers; } return name(smartName); }
/** * A filter for search. If a filter is required, will return it, otherwise, will return * <tt>null</tt>. */ @Nullable public Filter searchFilter(String... types) { boolean filterPercolateType = hasMapping(PercolatorService.TYPE_NAME); if (types != null && filterPercolateType) { for (String type : types) { if (PercolatorService.TYPE_NAME.equals(type)) { filterPercolateType = false; break; } } } Filter excludePercolatorType = null; if (filterPercolateType) { excludePercolatorType = new NotFilter(documentMapper(PercolatorService.TYPE_NAME).typeFilter()); } if (types == null || types.length == 0) { if (hasNested && filterPercolateType) { return new AndFilter(ImmutableList.of(excludePercolatorType, NonNestedDocsFilter.INSTANCE)); } else if (hasNested) { return NonNestedDocsFilter.INSTANCE; } else if (filterPercolateType) { return excludePercolatorType; } else { return null; } } // if we filter by types, we don't need to filter by non nested docs // since they have different types (starting with __) if (types.length == 1) { DocumentMapper docMapper = documentMapper(types[0]); if (docMapper == null) { return new TermFilter(new Term(types[0])); } return docMapper.typeFilter(); } // see if we can use terms filter boolean useTermsFilter = true; for (String type : types) { DocumentMapper docMapper = documentMapper(type); if (docMapper == null) { useTermsFilter = false; break; } if (!docMapper.typeMapper().fieldType().indexed()) { useTermsFilter = false; break; } } if (useTermsFilter) { BytesRef[] typesBytes = new BytesRef[types.length]; for (int i = 0; i < typesBytes.length; i++) { typesBytes[i] = new BytesRef(types[i]); } TermsFilter termsFilter = new TermsFilter(TypeFieldMapper.NAME, typesBytes); if (filterPercolateType) { return new AndFilter(ImmutableList.of(excludePercolatorType, termsFilter)); } else { return termsFilter; } } else { // Current bool filter requires that at least one should clause matches, even with a must // clause. XBooleanFilter bool = new XBooleanFilter(); for (String type : types) { DocumentMapper docMapper = documentMapper(type); if (docMapper == null) { bool.add( new FilterClause( new TermFilter(new Term(TypeFieldMapper.NAME, type)), BooleanClause.Occur.SHOULD)); } else { bool.add(new FilterClause(docMapper.typeFilter(), BooleanClause.Occur.SHOULD)); } } if (filterPercolateType) { bool.add(excludePercolatorType, BooleanClause.Occur.MUST); } return bool; } }
// never expose this to the outside world, we need to reparse the doc mapper so we get fresh // instances of field mappers to properly remove existing doc mapper private DocumentMapper merge(DocumentMapper mapper) { synchronized (typeMutex) { if (mapper.type().length() == 0) { throw new InvalidTypeNameException("mapping type name is empty"); } if (mapper.type().charAt(0) == '_' && !PercolatorService.TYPE_NAME.equals(mapper.type())) { throw new InvalidTypeNameException( "mapping type name [" + mapper.type() + "] can't start with '_'"); } if (mapper.type().contains("#")) { throw new InvalidTypeNameException( "mapping type name [" + mapper.type() + "] should not include '#' in it"); } if (mapper.type().contains(",")) { throw new InvalidTypeNameException( "mapping type name [" + mapper.type() + "] should not include ',' in it"); } if (mapper.type().contains(".")) { logger.warn( "Type [{}] contains a '.', it is recommended not to include it within a type name", mapper.type()); } // we can add new field/object mappers while the old ones are there // since we get new instances of those, and when we remove, we remove // by instance equality DocumentMapper oldMapper = mappers.get(mapper.type()); if (oldMapper != null) { DocumentMapper.MergeResult result = oldMapper.merge(mapper, mergeFlags().simulate(false)); if (result.hasConflicts()) { // TODO: What should we do??? if (logger.isDebugEnabled()) { logger.debug( "merging mapping for type [{}] resulted in conflicts: [{}]", mapper.type(), Arrays.toString(result.conflicts())); } } return oldMapper; } else { FieldMapperListener.Aggregator fieldMappersAgg = new FieldMapperListener.Aggregator(); mapper.traverse(fieldMappersAgg); addFieldMappers( fieldMappersAgg.mappers.toArray(new FieldMapper[fieldMappersAgg.mappers.size()])); mapper.addFieldMapperListener(fieldMapperListener, false); ObjectMapperListener.Aggregator objectMappersAgg = new ObjectMapperListener.Aggregator(); mapper.traverse(objectMappersAgg); addObjectMappers( objectMappersAgg.mappers.toArray(new ObjectMapper[objectMappersAgg.mappers.size()])); mapper.addObjectMapperListener(objectMapperListener, false); mappers = newMapBuilder(mappers).put(mapper.type(), mapper).map(); for (DocumentTypeListener typeListener : typeListeners) { typeListener.created(mapper.type()); } return mapper; } } }
public void close() { for (DocumentMapper documentMapper : mappers.values()) { documentMapper.close(); } }