簡體   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