Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何配置spring data mongodb以使用共享同一文档模型的两个不同mongo实例_Java_Mongodb_Spring Data Mongodb - Fatal编程技术网

Java 如何配置spring data mongodb以使用共享同一文档模型的两个不同mongo实例

Java 如何配置spring data mongodb以使用共享同一文档模型的两个不同mongo实例,java,mongodb,spring-data-mongodb,Java,Mongodb,Spring Data Mongodb,我在一家拥有多个品牌的公司工作,因此我们在一些不同的主机上有几个MongoDB实例,每个品牌上都有相同的文档模型。(相同的结构,不同的数据) 为了简单起见,假设我们有一个橙色品牌,数据库实例服务于端口27017,香蕉品牌的数据库实例服务于端口27018 目前,我正在开发一项欺诈检测服务,该服务需要连接到所有数据库,并一起分析所有客户的行为,而不考虑品牌 因此,我的“模型”有一个共享的实体,用于客户,并用@Document注释(org.springframework.data.mongodb.co

我在一家拥有多个品牌的公司工作,因此我们在一些不同的主机上有几个MongoDB实例,每个品牌上都有相同的文档模型。(相同的结构,不同的数据)

为了简单起见,假设我们有一个橙色品牌,数据库实例服务于端口27017,香蕉品牌的数据库实例服务于端口27018

目前,我正在开发一项欺诈检测服务,该服务需要连接到所有数据库,并一起分析所有客户的行为,而不考虑品牌

因此,我的“模型”有一个共享的实体,用于客户,并用@Document注释(org.springframework.data.mongodb.core.mapping.Document)

下一件事是两个mongoresposition,例如:

public interface BananaRepository extends MongoRepository<Customer, String>

    List<Customer> findAllByEmail(String email);

public interface OrangeRepository extends MongoRepository<Customer, String>

    List<Customer> findAllByEmail(String email);

公共接口BananaRepository扩展了MongoRepository
列出FindAllByMail(字符串电子邮件);
公共接口OrangeRepository扩展了MongoRepository
列出FindAllByMail(字符串电子邮件);
使用一些存根方法通过Id、电子邮件等查找客户。Spring负责为此类接口生成所有实现类(相当标准的Spring内容)

为了提示每个存储库连接到正确的mongodb实例,我需要两个Mongo配置,例如:


@Configuration
@EnableMongoRepositories(basePackageClasses = {Customer.class})
public class BananaConfig extends AbstractMongoConfiguration {

    @Value("${database.mongodb.banana.username:}")
    private String username;
    @Value("${database.mongodb.banana.database}")
    private String database;
    @Value("${database.mongodb.banana.password:}")
    private String password;
    @Value("${database.mongodb.banana.uri}")
    private String mongoUri;


    @Override
    protected Collection<String> getMappingBasePackages() {
        return Collections.singletonList("com.acme.model");
    }

    @Override
    protected String getDatabaseName() {
        return this.database;
    }

    @Override
    @Bean(name="bananaClient")
    public MongoClient mongoClient() {
        final String authString;

        //todo: Use MongoCredential
        //todo: Use ServerAddress
        //(See https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories) 10.3.4
        if ( valueIsPresent(username) ||valueIsPresent(password)) {
            authString = String.format("%s:%s@", username, password);
        } else {
            authString = "";
        }
        String conecctionString = "mongodb://" + authString + mongoUri + "/" + database;

        System.out.println("Going to connect to: " + conecctionString);

        return new MongoClient(new MongoClientURI(conecctionString, builder()
                .connectTimeout(5000)
                .socketTimeout(8000)
                .readPreference(ReadPreference.secondaryPreferred())
                .writeConcern(ACKNOWLEDGED)));

    }

    @Bean(name = "bananaTemplate")
    public MongoTemplate mongoTemplate(@Qualifier("bananaFactory") MongoDbFactory mongoFactory) {
        return new MongoTemplate(mongoFactory);
    }

    @Bean(name = "bananaFactory")
    public MongoDbFactory mongoFactory() {
        return new SimpleMongoDbFactory(mongoClient(),
                getDatabaseName());
    }



    private static int sizeOfValue(String value){
        if (value == null) return 0;
        return value.length();
    }
    private static boolean valueIsMissing(String value){
        return sizeOfValue(value) == 0;
    }
    private static boolean valueIsPresent(String value){
        return ! valueIsMissing(value);
    }
}

@配置
@EnableMongorPositories(basePackageClasses={Customer.class})
公共类BananaConfig扩展了AbstractMongoConfiguration{
@值(${database.mongodb.banana.username:})
私有字符串用户名;
@值(${database.mongodb.banana.database}”)
私有字符串数据库;
@值(${database.mongodb.banana.password:}”)
私有字符串密码;
@值(${database.mongodb.banana.uri})
蒙古里私人字符串;
@凌驾
受保护的集合getMappingBasePackages(){
returncollections.singletonList(“com.acme.model”);
}
@凌驾
受保护的字符串getDatabaseName(){
返回此数据库;
}
@凌驾
@Bean(name=“bananaClient”)
公共MongoClient MongoClient(){
最后一个字符串authString;
//todo:使用MongoCredential
//todo:使用服务器地址
//(见https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories) 10.3.4
if(valueIsPresent(用户名)| | valueIsPresent(密码)){
authString=String.format(“%s:%s@”,用户名,密码);
}否则{
authString=“”;
}
String conecctionString=“mongodb://”+authString+mongoUri+“/”+数据库;
System.out.println(“要连接到:“+conecctionString”);
返回新的MongoClient(新的MongoClientURI(conecctionString,builder())
.连接超时(5000)
.socketTimeout(8000)
.readPreference(readPreference.secondaryPreferred())
.writeConcern(已确认));
}
@Bean(name=“bananaTemplate”)
公共MongoTemplate MongoTemplate(@Qualifier(“bananaFactory”)MongoDB工厂mongoFactory){
返回新的MongoTemplate(mongoFactory);
}
@Bean(name=“bananaFactory”)
公共MongoDB工厂mongoFactory(){
返回新的SimpleMongoDbFactory(mongoClient(),
getDatabaseName());
}
私有静态int-sizeOfValue(字符串值){
if(value==null)返回0;
返回值.length();
}
私有静态布尔值丢失(字符串值){
返回sizeOfValue(value)==0;
}
私有静态布尔值Present(字符串值){
return!valueIsMissing(value);
}
}
I有类似的橙色配置,指向正确的mongo实例

我的服务是这样的:

    public List<? extends Customer> findAllByEmail(String email) {
        return  Stream.concat(
                bananaRepository.findAllByEmail(email).stream(),
                orangeRepository.findAllByEmail(email).stream())
                .collect(Collectors.toList());
       
    }

public List嗯,我有一个非常详细的答案,但是StackOverflow抱怨看起来像垃圾邮件,不允许我发布

完整的答案仍然可以作为


底线是,MongoRepository(接口)和模型对象必须放在同一个包中

更新:我发现了本文及其代码,尽管通过MongoProperties进行了不同的配置设置,但本文背后的关键概念是为每个配置提供单独的MongoTemplates,并将其连接起来,以便每个配置引用单独的模板。要记住一件重要的事情:模型和存储库都需要在同一个包中。否则它将不起作用,你将以误导性错误告终。因此,请引用上述文章:“为了能够创建多个MongoTemplate对象,有必要禁用mongodb的Spring引导自动配置。只需在application.properties文件中添加以下属性即可实现:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.mongoutoconfiguration
(本文引用application.yml,因此我将该属性转换为applications.properties语法)