我有这样的用例。我的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
...
}
]
但请注意,这既不是ASC也不是DESC,而是可以是/api/questions?id=2, id=7, id=4, id=5
我使用org.springframework.data.mongodb.repository.MongoRepository
作为我的DAO
课程。目前,我正在通过基于spring-data的存储库获取数据后在我的服务层内进行排序。该解决方案有效。但我更愿意在DAO存储库级别本身完成这种排序,因为它的成本更低,并且不会给服务层的业务逻辑增加不必要的复杂性。相反,我可以将责任仅委托给DB,假设它更有能力通过更多优化来完成这些事情。
我可以使用弹簧数据实现这一目标吗? 如果是这样的话怎么办呢?
答案 0 :(得分:4)
如果您使用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
}