【问题标题】:Spring Boot & MongoDB, Query nested map for keySpring Boot 和 MongoDB,查询嵌套映射的键
【发布时间】:2018-06-24 09:22:11
【问题描述】:

我正在尝试在 MongoDB 中查询在文档的嵌套映射中具有特定键的所有文档

{
   "_id" : ObjectId("5a5cd9711736c32c45f11adf"),
   "name" : "Test A",
   "userSubscription" : {
      "map" : {
          "1234" : true,
          "999" : true,
      }
   }
}

我查询如下:

db.getCollection('myColl').find( { "userSubscription.map" : {"1234":true }})

它正在工作,但是,它只返回包含单个值“1234”的文档,所以如果“userSubscription.map”包含“1234”“5555 " 查询没有显示任何结果。

我正在使用 Robo3T 来测试查询,并使用 SpringBoot 注释来查询这个, 答案可以在 Spring Boot 注释查询中吗?

Spring Boot 查询示例:

@Query("{QUERY : ?0}")
List<Person> findByUserSubscription(String key);

** "?0" 是使用第一种方法参数

谢谢!!!

更新:

现在文档看起来像这样:

{
"_id" : ObjectId("5a5cd9711736c32c45f11adf"),
   "name" : "Test A",    
   "userSubscription" : {
      "1234" : true,
      "3333" : true
    }
}

Robo 3T 查询:db.getCollection('Person').find({ "userSubscription.1234": {$exists : true} })

工作完美!

但是,Spring boot 中的查询看起来像:

@Query("{userSubscription.?0 : {$exists: true} }")

它没有显示任何结果...

什么问题???

【问题讨论】:

    标签: json mongodb spring-boot


    【解决方案1】:

    将地图建模为array of embedded documents like

    {
      "map" : [
         {k: "1234", v: true},
         {k: "999", v: true}
      ]
    }      
    

    你可以一键找到

    db.myColl.find({"userSubscription.map":{$elemMatch: { k: "1234", v: true } } })
    

    @Query("{'userSubscription.map':{$elemMatch: { k: ?0, v: true } } }")
    List<Person> findByUserSubscription(String key);
    

    `

    【讨论】:

    • 我无法理解如何从 java 代码中实现这种结构
    • 您必须先运行更新才能移动到新结构,然后才能进行查询。那是你在做什么? Here 就是这样一个例子。如果您不适合更新到新结构,则必须运行聚合。
    • 它不是实时数据库,因此我可以删除该集合。我不明白这种结构在 Java 代码中是如何表示的。 userSubscription 现在是一个包含键和值的 Map 对象数组?
    • 它不是实时数据库,因此我可以删除该集合。我不明白这种结构在 Java 代码中是如何表示的。 userSubscription 现在是一个带有键和值的 Map 对象数组?整个想法不是迭代整个数组,因此我可以使用 map 并且键将是唯一的......
    • 我同意您的方法,但 mongodb 无法以您的方式查询结构。等效的 mongodb 结构是嵌入文档的数组。所以要在java中建模,你可以使用List&lt;Map&lt;String, Object&gt;&gt;。不需要迭代,因为直接键查找是在服务器端执行的。如果您想保留结构,则必须使用聚合查询,该结构本质上是在查询之前将其转换为聚合管道中的 mongo db 结构
    【解决方案2】:

    在 Spring Data mongodb 中使用 Query 和 Criteria Class 有一个更简单的解决方案。如下:

    Query query = new Query();
    query.addCriteria(Criteria.where("userSubscription."+key).exists(true));
    return mongoTemplate.find(query, YourDocument.class);
    

    【讨论】:

      【解决方案3】:

      您错过了 @Query 的单引号。

      @Query("{'userSubscription.?0' : {$exists: true} }")
      

      【讨论】:

        猜你喜欢
        • 2021-12-15
        • 1970-01-01
        • 2020-05-18
        • 2017-10-16
        • 2021-09-22
        • 2021-12-15
        • 2017-05-27
        • 2014-04-08
        • 1970-01-01
        相关资源
        最近更新 更多