@Indexed для вложенного свойства, не работающего в Spring-data для mongo

У меня следующая структура объекта:

@Document(collection = "user")
@TypeAlias("user")
public class User {
    @Id
    private ObjectId id;
    private Contact info = new Contact();
}

а вот контактное pojo:

public class Contact {
    @Indexed(unique = true)
    private String mail;
}

Но по неизвестным мне причинам я не вижу, чтобы Spring-data создавал уникальный индекс для свойства info.mail.

Подводя итог, у меня есть эта json-структура пользовательского объекта: {_id: xxxxx, info: {mail: "[email protected]"}}

И я хочу создать уникальный индекс для info.mail, используя данные Spring с указанной выше структурой pojo. Пожалуйста помоги.


person hellojava    schedule 10.03.2014    source источник
comment
какую версию spring-data-mongodb вы используете?   -  person Christoph Strobl    schedule 23.01.2015


Ответы (3)


Насколько я помню, аннотировать встроенные поля с помощью @Indexed не получится. @CompoundIndex - это путь:

@Document(collection = "user")
@TypeAlias("user")
@CompoundIndexes({
    @CompoundIndex(name = "contact_email", def = "{ 'contact.mail': 1 }", unique = true)
})
public class User {
    @Id
    private ObjectId id;
    private Contact info = new Contact();
}
person Maciej Walkowiak    schedule 14.03.2014
comment
Не могли бы вы направить меня сюда: stackoverflow.com/questions/61948943/ - person Pra_A; 22.05.2020
comment
При необходимости вам, возможно, придется использовать аннотацию @Field, как описано здесь. Но для меня он отлично работает и без него, если я удалю внешний тег @CompoundIndexes и буду использовать только аннотацию @CompoundIndex. - person iamfrank; 30.04.2021

В моем случае у меня было свежее приложение весенней загрузки 2.3.0 только с аннотациями @Document, @Id и @Indexed. Мне удалось получить и вставить документы, но он отказался создать индекс, отличный от PK. Наконец я понял, что есть свойство, которое нужно включить.

spring.data.mongodb.auto-index-creation = true

На самом деле он работает даже с вложенными объектами без аннотации @Document.

Надеюсь это поможет :)

person Xenobius    schedule 23.06.2020
comment
Для «AbstractMongoClientConfiguration» это «public boolean autoIndexCreation ()», которое по умолчанию является ложным. - person learner; 27.01.2021
comment
это сработало для меня - person Farkhod Daniyarov; 30.01.2021

Устаревший ответ, это было с более старой версией mongodb 1.x.


Была такая же проблема, похоже, что в вашем классе Contact отсутствует аннотация @Document, т.е.

@Document
public class Contact {
    @Indexed(unique = true)
    private String mail;
}

Должно работать, процитируйте справочник Spring mongodb.

Автоматическое создание индекса выполняется только для типов, аннотированных @Document.

person cristobal    schedule 23.01.2015
comment
Я думаю, что любой встроенный документ не требует @Document, потому что это не настоящий документ, а просто файл документа. - person db80; 12.02.2016
comment
Конечно, но вам все равно нужно намекнуть реализации Spring MongoDB DSL о том, как преобразовывать и использовать классы, которые она должна была индексировать. Spring MongoDB выполнит внутренний синтаксический анализ классов для каждого класса, использующего аннотацию @Document, и применит для него параметр @Indexed. Вы можете применить автоматический index через консоль mongo или через java-код, если хотите. Но если вы хотите воспользоваться автоматическими функциями, которые Spring делает для вас, вам просто нужно следовать правилам документации: P - person cristobal; 12.02.2016
comment
В противном случае для реализации Spring Mongo было бы сложно просто проанализировать все java-файлы во встроенном коде и проверить все поля для каждого класса, помеченного аннотацией @Indexed. Чем больше кодовая база, тем больше времени потребуется. Таким образом, причина, по которой у них есть @Document, заключается в том, чтобы намекнуть реализации Spring Mongo о том, какие файлы проверять, и применить параметр @Indexed, если он установлен. - person cristobal; 12.02.2016
comment
Я имел в виду, что вам не нужно добавлять аннотации во встроенный документ. Если вам нужно проиндексировать поле встроенного документа, вы должны использовать @CompoundIndex в родительском классе. - person db80; 12.02.2016
comment
Мне кажется странным, что документация для Spring Mongo ясно показывает все примеры использования @CompoundIndex в сочетании с использованием аннотации @Docucment. - person cristobal; 12.02.2016
comment
Хорошо, я понимаю, что вы говорите, расширьте родительский класс с помощью аннотации @Document. Конечно, это сработает, но это скорее выбор кода / стиля. Я предпочитаю иметь каждый базовый @Document класс, который входит в mongodb как последний класс, не имеющий наследования. - person cristobal; 12.02.2016
comment
@cristobal Почему этот индекс создается каждый раз, когда соединение Mongo устанавливается с использованием Indexed для свойства класса? Не вызывает ли это перегрузки базы данных? Я вижу в журналах, что индексы создаются каждый раз. - person Adnan; 09.01.2019
comment
@Adnan, весенний драйвер mongo db, который я тогда использовал, предназначен для старого mongo db impl. Что касается вашего вопроса, я не могу вспомнить, что происходило. Может случиться так, что этот ответ не относится к драйверу spring mongodb и версии mongodb, которую вы используете в настоящее время. - person cristobal; 09.01.2019
comment
@Adnan извините за поздний ответ, этот ответ был для более старого драйвера mongo db, и я пометил ответ как устаревший. - person cristobal; 23.04.2020