当前位置: 首页 > 知识库问答 >
问题:

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

督烨赫
2023-03-14

我有一个这样的用例。我在Mongo DB中有问题,有CRUD微服务。在那里,我公开了一个API方法,通过查询参数提供的ID列表获取问题。比如说,为了简单起见,用户会提出一些问题?id=2,id=7,id=4,id=5

然后我需要按照同样的顺序返回问题列表,如下所示

questions: [
    {
       id: 2,
       prompt: "prompt one",
       ...
    },
    {
        id: 7,
        prompt: "prompt two",
        ...
    },
    {
        id: 4,
        ...
    },
    {
        id: 5
        ...
    }
]

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

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

我可以使用spring数据实现这一点吗?如果是这样的话,怎么做呢?

共有1个答案

慕弘义
2023-03-14

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

public interface MyRepository extends MongoRepository<Question, String>{

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

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

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

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

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

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

/* 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"
}

那么聚合管道必须看起来像:

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
        }
    }
])

我得到的结果如下:

/* 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
}
 类似资料:
  • 问题内容: 这是一个快速的为您服务的: 我有一个ID列表,我想用它返回QuerySet(或数组(如果需要的话)),但是我想保持该顺序。 谢谢 问题答案: 我认为你不能在数据库级别强制执行该特定命令,因此你需要使用python来代替。 这将建立一个以id为键的对象字典,因此在建立排序列表时可以轻松检索它们。

  • 在一个<代码>中

  • 问题内容: 我有一个JSON文件,其中包含一些我想在AngularJS网站上访问的数据。现在,我要从数组中仅获取一个对象。因此,我想例如ID为1的商品。 数据如下所示: 我想使用AngularJS $ http功能加载数据,如下所示: 这正在工作。但是,现在如何从获取的数组中获取特定的数据对象(按ID)呢? 在此先感谢您的帮助。 马克·马克 问题答案: 唯一的方法就是遍历数组。显然,如果您确定结果

  • 问题内容: 我有类似的东西 如果我只是这样做,它将以ID升序返回行。有没有一种方法可以按照IN语句中给出的顺序取回行? 问题答案: 您应该使用“ ORDER BY FIELD”。因此,例如:

  • 问题内容: 我正在使用Firebase,直到最近我都没有按字母顺序获取数据的问题。我从来没有使用过查询,我总是只使用数据快照并逐一对其进行排序。最近,在 snapVal中 ,数据并不总是按字母顺序 排列 。如何做到这一点,以便获得按字母顺序排序的数据的snapVal,就像数据库快照中的快照一样? 真实示例:有4条消息,id1-id4(按此顺序)。它们包含消息“ 1”-“ 4”。快照看起来正确。但是

  • 在我的Spring Boot/Spring Data MongoDB项目中,我有以下POJO: 其中: 是一个复合对象数组,例如: 我做错了什么?如何调整代码,以便在包含数据的情况下,通过正确查找文档。 更新 这是一个示例文档,我将使用它作为键(在UI上选择的每个用户每次该文档中的信息都不同):