/** * Creates a new {@link IndexResolver} given {@link MongoMappingContext}. * * @param mappingContext must not be {@literal null}. * @return the new {@link IndexResolver}. * @since 2.2 */ static IndexResolver create(MongoMappingContext mappingContext) { Assert.notNull(mappingContext, "MongoMappingContext must not be null!"); return new MongoPersistentEntityIndexResolver(mappingContext); }
private void guradAndPotentiallyAddIndexForProperty(MongoPersistentProperty persistentProperty, String dotPath, Path path, String collection, List<IndexDefinitionHolder> indexes, CycleGuard guard) { String propertyDotPath = (StringUtils.hasText(dotPath) ? dotPath + "." : "") + persistentProperty.getFieldName(); Path propertyPath = path.append(persistentProperty); guard.protect(persistentProperty, propertyPath); if (persistentProperty.isEntity()) { try { indexes.addAll(resolveIndexForClass(persistentProperty.getTypeInformation().getActualType(), propertyDotPath, propertyPath, collection, guard)); } catch (CyclicPropertyReferenceException e) { LOGGER.info(e.getMessage()); } } IndexDefinitionHolder indexDefinitionHolder = createIndexDefinitionHolderForProperty(propertyDotPath, collection, persistentProperty); if (indexDefinitionHolder != null) { indexes.add(indexDefinitionHolder); } }
appendTextIndexInformation("", Path.empty(), indexDefinitionBuilder, root, new TextIndexIncludeOptions(IncludeStrategy.DEFAULT), new CycleGuard()); } catch (CyclicPropertyReferenceException e) {
@Nullable private IndexDefinitionHolder createIndexDefinitionHolderForProperty(String dotPath, String collection, MongoPersistentProperty persistentProperty) { if (persistentProperty.isAnnotationPresent(Indexed.class)) { return createIndexDefinition(dotPath, collection, persistentProperty); } else if (persistentProperty.isAnnotationPresent(GeoSpatialIndexed.class)) { return createGeoSpatialIndexDefinition(dotPath, collection, persistentProperty); } return null; }
/** * Recursively resolve and inspect properties of given {@literal type} for indexes to be created. * * @param type * @param dotPath The {@literal "dot} path. * @param path {@link PersistentProperty} path for cycle detection. * @param collection * @param guard * @return List of {@link IndexDefinitionHolder} representing indexes for given type and its referenced property * types. Will never be {@code null}. */ private List<IndexDefinitionHolder> resolveIndexForClass(final TypeInformation<?> type, final String dotPath, final Path path, final String collection, final CycleGuard guard) { MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(type); final List<IndexDefinitionHolder> indexInformation = new ArrayList<>(); indexInformation.addAll(potentiallyCreateCompoundIndexDefinitions(dotPath, collection, entity)); entity.doWithProperties((PropertyHandler<MongoPersistentProperty>) property -> this .guradAndPotentiallyAddIndexForProperty(property, dotPath, path, collection, indexInformation, guard)); indexInformation.addAll(resolveIndexesForDbrefs(dotPath, collection, entity)); return indexInformation; }
@SuppressWarnings("deprecation") protected IndexDefinitionHolder createCompoundIndexDefinition(String dotPath, String collection, CompoundIndex index, MongoPersistentEntity<?> entity) { CompoundIndexDefinition indexDefinition = new CompoundIndexDefinition( resolveCompoundIndexKeyFromStringDefinition(dotPath, index.def())); if (!index.useGeneratedName()) { indexDefinition.named(pathAwareIndexName(index.name(), dotPath, null)); } if (index.unique()) { indexDefinition.unique(); } if (index.sparse()) { indexDefinition.sparse(); } if (index.background()) { indexDefinition.background(); } return new IndexDefinitionHolder(dotPath, indexDefinition, collection); }
private void checkForAndCreateIndexes(final MongoPersistentEntityIndexResolver indexResolver, final MongoPersistentEntity<?> entity) { // make sure its a root document if (entity.findAnnotation(Document.class) != null) { for (IndexDefinitionHolder indexDefinitionHolder : indexResolver.resolveIndexForClass(entity.getType())) { // work because of javas reentered lock feature this.mongoTemplate.indexOps(entity.getType()).ensureIndex(indexDefinitionHolder); } } } }
/** * Creates {@link IndexDefinition} wrapped in {@link IndexDefinitionHolder} out of {@link GeoSpatialIndexed} for * {@link MongoPersistentProperty}. * * @param dotPath The properties {@literal "dot"} path representation from its document root. * @param collection * @param persistentProperty * @return */ @Nullable protected IndexDefinitionHolder createGeoSpatialIndexDefinition(String dotPath, String collection, MongoPersistentProperty persistentProperty) { GeoSpatialIndexed index = persistentProperty.findAnnotation(GeoSpatialIndexed.class); if (index == null) { return null; } GeospatialIndex indexDefinition = new GeospatialIndex(dotPath); indexDefinition.withBits(index.bits()); indexDefinition.withMin(index.min()).withMax(index.max()); if (!index.useGeneratedName()) { indexDefinition.named(pathAwareIndexName(index.name(), dotPath, persistentProperty)); } indexDefinition.typed(index.type()).withBucketSize(index.bucketSize()).withAdditionalField(index.additionalField()); return new IndexDefinitionHolder(dotPath, indexDefinition, collection); }
private List<IndexDefinitionHolder> potentiallyCreateCompoundIndexDefinitions(String dotPath, String collection, MongoPersistentEntity<?> entity) { if (entity.findAnnotation(CompoundIndexes.class) == null && entity.findAnnotation(CompoundIndex.class) == null) { return Collections.emptyList(); } return createCompoundIndexDefinitions(dotPath, collection, entity); }
private void resolveAndAddIndexesForAssociation(Association<MongoPersistentProperty> association, List<IndexDefinitionHolder> indexes, String path, String collection) { MongoPersistentProperty property = association.getInverse(); String propertyDotPath = (StringUtils.hasText(path) ? path + "." : "") + property.getFieldName(); if (property.isAnnotationPresent(GeoSpatialIndexed.class) || property.isAnnotationPresent(TextIndexed.class)) { throw new MappingException( String.format("Cannot create geospatial-/text- index on DBRef in collection '%s' for path '%s'.", collection, propertyDotPath)); } IndexDefinitionHolder indexDefinitionHolder = createIndexDefinitionHolderForProperty(propertyDotPath, collection, property); if (indexDefinitionHolder != null) { indexes.add(indexDefinitionHolder); } }
/** * Create {@link IndexDefinition} wrapped in {@link IndexDefinitionHolder} for {@link CompoundIndexes} of given type. * * @param dotPath The properties {@literal "dot"} path representation from its document root. * @param fallbackCollection * @param type * @return */ protected List<IndexDefinitionHolder> createCompoundIndexDefinitions(String dotPath, String fallbackCollection, MongoPersistentEntity<?> entity) { List<IndexDefinitionHolder> indexDefinitions = new ArrayList<>(); CompoundIndexes indexes = entity.findAnnotation(CompoundIndexes.class); if (indexes != null) { indexDefinitions = Arrays.stream(indexes.value()) .map(index -> createCompoundIndexDefinition(dotPath, fallbackCollection, index, entity)) .collect(Collectors.toList()); } CompoundIndex index = entity.findAnnotation(CompoundIndex.class); if (index != null) { indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index, entity)); } return indexDefinitions; }
/** * Recursively resolve and inspect properties of given {@literal type} for indexes to be created. * * @param type * @param dotPath The {@literal "dot} path. * @param path {@link PersistentProperty} path for cycle detection. * @param collection * @param guard * @return List of {@link IndexDefinitionHolder} representing indexes for given type and its referenced property * types. Will never be {@code null}. */ private List<IndexDefinitionHolder> resolveIndexForClass(final TypeInformation<?> type, final String dotPath, final Path path, final String collection, final CycleGuard guard) { MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(type); final List<IndexDefinitionHolder> indexInformation = new ArrayList<>(); indexInformation.addAll(potentiallyCreateCompoundIndexDefinitions(dotPath, collection, entity)); entity.doWithProperties((PropertyHandler<MongoPersistentProperty>) property -> this .guradAndPotentiallyAddIndexForProperty(property, dotPath, path, collection, indexInformation, guard)); indexInformation.addAll(resolveIndexesForDbrefs(dotPath, collection, entity)); return indexInformation; }
@Nullable private IndexDefinitionHolder createIndexDefinitionHolderForProperty(String dotPath, String collection, MongoPersistentProperty persistentProperty) { if (persistentProperty.isAnnotationPresent(Indexed.class)) { return createIndexDefinition(dotPath, collection, persistentProperty); } else if (persistentProperty.isAnnotationPresent(GeoSpatialIndexed.class)) { return createGeoSpatialIndexDefinition(dotPath, collection, persistentProperty); } return null; }
@SuppressWarnings("deprecation") protected IndexDefinitionHolder createCompoundIndexDefinition(String dotPath, String collection, CompoundIndex index, MongoPersistentEntity<?> entity) { CompoundIndexDefinition indexDefinition = new CompoundIndexDefinition( resolveCompoundIndexKeyFromStringDefinition(dotPath, index.def())); if (!index.useGeneratedName()) { indexDefinition.named(pathAwareIndexName(index.name(), dotPath, null)); } if (index.unique()) { indexDefinition.unique(); } if (index.sparse()) { indexDefinition.sparse(); } if (index.background()) { indexDefinition.background(); } return new IndexDefinitionHolder(dotPath, indexDefinition, collection); }
indexDefinition.named(pathAwareIndexName(index.name(), dotPath, persitentProperty));
private List<IndexDefinitionHolder> potentiallyCreateCompoundIndexDefinitions(String dotPath, String collection, MongoPersistentEntity<?> entity) { if (entity.findAnnotation(CompoundIndexes.class) == null && entity.findAnnotation(CompoundIndex.class) == null) { return Collections.emptyList(); } return createCompoundIndexDefinitions(dotPath, collection, entity); }
private void resolveAndAddIndexesForAssociation(Association<MongoPersistentProperty> association, List<IndexDefinitionHolder> indexes, String path, String collection) { MongoPersistentProperty property = association.getInverse(); String propertyDotPath = (StringUtils.hasText(path) ? path + "." : "") + property.getFieldName(); if (property.isAnnotationPresent(GeoSpatialIndexed.class) || property.isAnnotationPresent(TextIndexed.class)) { throw new MappingException( String.format("Cannot create geospatial-/text- index on DBRef in collection '%s' for path '%s'.", collection, propertyDotPath)); } IndexDefinitionHolder indexDefinitionHolder = createIndexDefinitionHolderForProperty(propertyDotPath, collection, property); if (indexDefinitionHolder != null) { indexes.add(indexDefinitionHolder); } }
/** * Create {@link IndexDefinition} wrapped in {@link IndexDefinitionHolder} for {@link CompoundIndexes} of given type. * * @param dotPath The properties {@literal "dot"} path representation from its document root. * @param fallbackCollection * @param type * @return */ protected List<IndexDefinitionHolder> createCompoundIndexDefinitions(String dotPath, String fallbackCollection, MongoPersistentEntity<?> entity) { List<IndexDefinitionHolder> indexDefinitions = new ArrayList<>(); CompoundIndexes indexes = entity.findAnnotation(CompoundIndexes.class); if (indexes != null) { indexDefinitions = Arrays.stream(indexes.value()) .map(index -> createCompoundIndexDefinition(dotPath, fallbackCollection, index, entity)) .collect(Collectors.toList()); } CompoundIndex index = entity.findAnnotation(CompoundIndex.class); if (index != null) { indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index, entity)); } return indexDefinitions; }
private void potentiallyAddIndexForProperty(MongoPersistentEntity<?> root, MongoPersistentProperty persistentProperty, List<IndexDefinitionHolder> indexes, CycleGuard guard) { try { if (persistentProperty.isEntity()) { indexes.addAll(resolveIndexForClass(persistentProperty.getTypeInformation().getActualType(), persistentProperty.getFieldName(), Path.of(persistentProperty), root.getCollection(), guard)); } IndexDefinitionHolder indexDefinitionHolder = createIndexDefinitionHolderForProperty( persistentProperty.getFieldName(), root.getCollection(), persistentProperty); if (indexDefinitionHolder != null) { indexes.add(indexDefinitionHolder); } } catch (CyclicPropertyReferenceException e) { LOGGER.info(e.getMessage()); } }
/** * Creates a new {@link ReactiveMongoPersistentEntityIndexCreator} for the given {@link MongoMappingContext}, * {@link ReactiveIndexOperationsProvider}. * * @param mappingContext must not be {@literal null}. * @param operationsProvider must not be {@literal null}. */ public ReactiveMongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, ReactiveIndexOperationsProvider operationsProvider) { this(mappingContext, operationsProvider, new MongoPersistentEntityIndexResolver(mappingContext)); }