代码之家  ›  专栏  ›  技术社区  ›  Johan

用Spring数据分割投影MongoDB ReactiveMongoRepository?

  •  0
  • Johan  · 技术社区  · 8 年前

    我有一个收藏名为 myCollection 包含以下格式的文档:

    {
        "_id" : "1",
        "myArray" : [ { x: 1, y: "a" }, { x: 2, y: "b" }, { x: 3, y: "c" }, { x: 4, y: "d" }, { x: 5, y: "e" }]
    }
    

    我想做的是构造一个返回 slice 中的某些元素 myArray 作为投影。

    也就是说,我的文档定义如下:

    @Document(collection = "myCollection")
    data class MyDocument(@Id val myId : String, val myArray : List<MyItem>)
    

    哪里 MyItem 定义如下:

    data class MyItem(val x: Int, val y: String)
    

    现在我要创建一个函数,它返回 我的项目 给定某个偏移量和项目计数(或“页面”),对于 MyDocument 有特定的身份证。

    这就是我试过的 projections ):

    data class MyArrayProjection(val myArray: List<MyItem>)
    
    interface MyRepository : ReactiveMongoRepository<MyDocument, String> {             
        fun findByMyId(myId: String, pageable: Pageable): Flux<MyArrayProjection>
    }
    

    我想看看当调用这个函数时,例如。

    myRepository.findByMyId("1", PageRequest.of(1, 2))
    

    它返回一个 Flux 包含 MyItem(x=3, y="c") MyItem(x=4, y="d") 但是它是空的。

    生成的MongoDB查询如下所示:

    {
        "find" : "myCollection",
        "filter" : {
            "_id" : "1"
        },
        "projection" : {
            "myArray" : 1
        },
        "skip" : 2,
        "limit" : 2,
        "batchSize" : 256
    }
    

    我怀疑发生的是 Pageable 实例对聚合操作( 我的文档 )而不是“内在的” 肌阵 这就是为什么我怀疑我想用 $slice 而是接线员。

    我怎样才能做到这一点?如果使用 ReactiveMongoRepository 那么我可以用 ReactiveMongoOperations .

    1 回复  |  直到 8 年前
        1
  •  0
  •   Johan    8 年前

    我设法通过改变:

    interface MyRepository : ReactiveMongoRepository<MyDocument, String> {             
        fun findByMyId(myId: String, pageable: Pageable): Flux<MyArrayProjection>
    }
    

    到:

    interface MyRepository : ReactiveMongoRepository<MyDocument, String> {             
        @Query(value = "{ '_id' : ?0 }", fields = "{ 'myArray': { '\$slice': ?1 } }")
        fun findByMyId(myId: String, slice: Array<Int>): Flux<MyArrayProjection>
    }
    

    然后使用以下方法调用它:

    myRepository.findByMyId("1", arrayOf(1, 2))