MongoDB 中的结果顺序与 $in 类似 MySQL field('_id', ...)
Posted
技术标签:
【中文标题】MongoDB 中的结果顺序与 $in 类似 MySQL field(\'_id\', ...)【英文标题】:Order of results in MongoDB with $in like MySQL field('_id', ...)MongoDB 中的结果顺序与 $in 类似 MySQL field('_id', ...) 【发布时间】:2015-02-15 23:31:46 【问题描述】:我正在使用 MongoDB 构建一个非常奇特的“趋势”帖子算法。由于该算法消耗大量时间,我在 cron 任务中执行我的算法,然后缓存一个排序的帖子 ID 数组。像这样(php vardump):
"trending" => array("548ac5ce05ea675e468b4966", "5469c6d5039069a5030041a7", ...)
关键是我找不到使用 MongoDB 以该顺序检索它们的任何方法。 使用 mysql 只需这样做:
SELECT * FROM posts
ORDER BY FIELD(_id, '548ac5ce05ea675e468b4966', '5469c6d5039069a5030041a7',...)
到目前为止,我尝试的是可以创建here,所以现在我可以检索带有权重的排序列表,但不能检索帖子。响应是这样的:
"result" : [
"_id" : ObjectId("548ac5ce05ea675e468b4966"),
"weight" : 1
,
"_id" : ObjectId("5469c6d5039069a5030041a7"),
"weight" : 2
],
"ok" : 1
有没有人做到这一点,甚至知道从哪里开始?
谢谢!
【问题讨论】:
【参考方案1】:我来自您链接的 SO 帖子。我发现是使用MongoDB提供的$$ROOT变量。
我的代码如下所示:
var ids = [456, 123, 789]
, stack = []
;
// Note that `i` is decremented here, not incremented like
// in the linked SO post. I think they have a typo.
for (var i = ids.length-1; i > 0; i--)
var rec =
$cond: [
$eq: ['$_id', ids[i - 1]],
i
]
;
if (stack.length === 0)
rec.$cond.push(i + 1);
else
var lval = stack.pop();
rec.$cond.push(lval);
stack.push(rec);
var pipeline = [
$match:
_id: $in: ids
,
$project:
weight: stack[0],
data: '$$ROOT' // This will give you the whole document.
,
$sort: weight: 1
];
Posts.aggregate(pipeline, function (err, posts)
if (err) return next();
// Use Underscore to grab the docs stored on `data` from above.
res.json(_.pluck(posts, 'data'));
);
请注意,我个人并不确定在构建查询的 for
循环中发生了什么。 :-P 所以大部分功劳都应该归功于他们。此外,我还不确定虚拟字段(如果您使用的是 Mongoose,就像我一样)会包含在这里,但我怀疑不会。
【讨论】:
以上是关于MongoDB 中的结果顺序与 $in 类似 MySQL field('_id', ...)的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB 使用 Async.js 与 $in 保持顺序 [重复]