SpringData - MongoDB 按给定顺序按 ID 获取对象

Rav*_*ala 4 java spring mongodb spring-data spring-boot

我有一个这样的用例。我在我的 Mongo DB 中有问题并且有一个 CRUD 微服务。在那里,我公开了一种 API 方法,可以通过查询参数给出的 ID 列表来获取问题。让我们说为了简单起见,用户给出/api/questions?id=2, id=7, id=4, id = 5

然后我需要以完全相同的顺序返回问题列表,就像这样

questions: [
    {
       id: 2,
       prompt: "prompt one",
       ...
    },
    {
        id: 7,
        prompt: "prompt two",
        ...
    },
    {
        id: 4,
        ...
    },
    {
        id: 5
        ...
    }
]
Run Code Online (Sandbox Code Playgroud)

但请注意,这既不是 ASC 也不是 DESC,而是可以是任意顺序,例如 /api/questions?id=2, id=7, id=4, id=5

我正在使用org.springframework.data.mongodb.repository.MongoRepository我的DAO班级。目前,我正在通过基于 spring-data 的存储库获取数据后在我的服务层内进行排序。该解决方案有效。但我更愿意在 DAO 存储库级别本身完成此排序,因为它成本更低,并且不会在服务层为我的业务逻辑增加不必要的复杂性。相反,我可以仅将责任委托给数据库,假设它更有能力通过更多优化来完成这些事情。

Mongo 文档结构如下所示。 在此处输入图片说明

我可以使用弹簧数据实现这一点吗?如果是这样,如何完成那件事?

Ale*_* P. 5

如果您正在使用,MongoRepository则创建一个扩展它的接口。例子:

public interface MyRepository extends MongoRepository<Question, String>{

    @Query("{_id: { $in: ?0 } })")
    List<Question> findByIds(List<String> ids, Sort sort);
}
Run Code Online (Sandbox Code Playgroud)

然后在您的服务类或任何您使用存储库的地方。添加以下内容:

Sort sort = new Sort(Direction.ASC,"_id"); // Or DESC
List<Question> questionsById = repository.findByIds(ids, sort);
Run Code Online (Sandbox Code Playgroud)

当然这里的问题是我创建的一个虚拟类来测试它,用你的替换它。


好的,如果您需要输入用户订单,那么您真的无法使用聚合框架。

如果我的数据库中有以下数据集按该顺序插入:

/* 1 */
{
    "_id" : ObjectId("5a103a434d8a2fe38bec5c5e"),
    "prompt" : "prompt one"
}

/* 2 */
{
    "_id" : ObjectId("5a103a434d8a2fe38bec5c60"),
    "prompt" : "prompt two"
}

/* 3 */
{
    "_id" : ObjectId("5a103a434d8a2fe38bec5c62"),
    "prompt" : "prompt three"
}

/* 4 */
{
    "_id" : ObjectId("5a103a434d8a2fe38bec5c64"),
    "prompt" : "prompt four"
}
Run Code Online (Sandbox Code Playgroud)

然后聚合管道必须看起来像:

db.getCollection('questions').aggregate([{
        "$match": {
            "_id": {
                "$in": [ObjectId("5a103a434d8a2fe38bec5c62"), ObjectId("5a103a434d8a2fe38bec5c60"), ObjectId("5a103a434d8a2fe38bec5c64"), ObjectId("5a103a434d8a2fe38bec5c5e")]
            },
        }
    },
    {
        "$project": {
            "orderByInputId": {
                "$cond": [{
                        "$eq": ["$_id", ObjectId("5a103a434d8a2fe38bec5c62")]
                    },
                    1,
                    {
                        "$cond": [{
                                "$eq": ["$_id", ObjectId("5a103a434d8a2fe38bec5c60")]
                            },
                            2,
                            {
                                "$cond": [{
                                        "$eq": ["$_id", ObjectId("5a103a434d8a2fe38bec5c64")]
                                    },
                                    3,
                                    4
                                ]
                            }
                        ]
                    }
                ]
            },
            prompt: 1
        }
    },

    // Sort the results
    {
        "$sort": {
            "orderByInputId": 1
        }
    }
])
Run Code Online (Sandbox Code Playgroud)

我得到的结果如下:

/* 1 */
{
    "_id" : ObjectId("5a103a434d8a2fe38bec5c62"),
    "prompt" : "prompt three",
    "orderByInputId" : 1.0
}

/* 2 */
{
    "_id" : ObjectId("5a103a434d8a2fe38bec5c60"),
    "prompt" : "prompt two",
    "orderByInputId" : 2.0
}

/* 3 */
{
    "_id" : ObjectId("5a103a434d8a2fe38bec5c64"),
    "prompt" : "prompt four",
    "orderByInputId" : 3.0
}

/* 4 */
{
    "_id" : ObjectId("5a103a434d8a2fe38bec5c5e"),
    "prompt" : "prompt one",
    "orderByInputId" : 4.0
}
Run Code Online (Sandbox Code Playgroud)