繁体   English   中英

如何在spring-boot程序中使用条件访问mongoDB中的子文档

[英]How to access sub-document in mongoDB with condition in spring-boot program

我想编写一个spring-boot程序来获取name,id和key的值,其中abc.active为true。 我写了一些代码

@Repository
public interface SwitchRepoDao extends MongoRepository< SwitchRepo, String> {
     public List<SwitchRepo> findByAbc_active(boolean active);
}

另外,我已经编写了接口类。

@Document(collection="switchrepo")
public class SwitchRepo{

    @Id
    private String id;
    private String type;
    private List<Abc> abc;
    // with getters and setters also constructors.

Abc是上课的。

public class Abc{

    private String name;
    private String id;
    private String key;
    private boolean active;

这是我用来显示输出的代码。

    @Bean
    CommandLineRunner runner(SwitchRepoDao switchRepoDao) {
        return new CommandLineRunner() {
            @Override
            public void run(String... args) throws Exception {          



                Iterable<SwitchRepo> personList = switchRepoDao.findAllWithStatus(true);
                System.out.println("Configuration : ");
                for (SwitchRepo config : personList)
        {
                System.out.println(config.getRegistries().toString());
        }

            }
        };
    }

任何人都可以帮我这个。 对于任何查询相关的问题做评论。 先感谢您。

以下是来自数据库测试的MongoDB Collection。 和集合名称是switchrepo。

"_id" : "1234567890",
    "type" : "xyz",
    "abc" : [ 
        {
            "name" : "test",
            "id" : "test1",
            "key" : "secret",
            "active" : true
        }, 
        {
            "name" : "test2",
            "id" : "test12",
            "key" : "secret2",
            "active" : false
        }
    ]
}

作为回应,我需要输出为

        "id" : "test1",
        "key" : "secret",
        "active" : true

因为在该子文档数组中active是正确的。

实际结果我得到的是"abc" : [{"name" : "test","id" : "test1","key" : "secret","active" : true},{"name" : "test2","id" : "test12","key" : "secret2","active" : false}]

当字段类型是数组时,不能将属性表达式用于proprety。

这里使用@Query或Aggregations的解决方案

解决方案1(使用@Query)

@Repository
public interface SwitchRepoDao extends MongoRepository< SwitchRepo, String> {
 //public List<SwitchRepo> findByAbc_active(boolean active);

 @Query(value = "{ 'abc.active' : ?0}", fields = "{ 'abc' : 1 }")
 List<SwitchRepo> findAllWithStatus(Boolean status);

}

{ 'abc.active' : ?0}  for filtring

{ 'abc' : 1 }         for only return that part of the document (abc).

调用findAllWithStatus将返回所有具有至少一个带有active的ABC的SwitchRepo为true,你需要过滤(使用java 8流过滤器,例如所有没有活动的Abc来自数组)

解决方案2(使用Mongodb聚合)

创建一个新的dto类

import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection="switchrepo")
public class SwitchRepoDto {

  @Id
  private String id;
  private String type;
  private Abc abc;
// with getters and setters also constructors.


  public SwitchRepoDto() {
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getType() {
    return type;
  }

  public void setType(String type) {
    this.type = type;
  }

  public Abc getAbc() {
    return abc;
  }

  public void setAbc(Abc abc) {
    this.abc = abc;
  }
}

创建自定义方法向Repository添加自定义方法或将MongoOperations注入服务层。

    @Autowired
    private MongoOperations mongoOperations;

    public List<SwitchRepoDto> findAllActive() {

        UnwindOperation unwind =  Aggregation.unwind("$abc");
        MatchOperation match = Aggregation.match(Criteria.where("abc.active").is(true));
        Aggregation aggregation = Aggregation.newAggregation(unwind,match);
        AggregationResults<SwitchRepoDto> results = mongoOperations.aggregate(aggregation, SwitchRepoDto.class, SwitchRepoDto.class);
        List<SwitchRepoDto> mappedResults = results.getMappedResults();

        return mappedResults;

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM