我希望获得"lastseen":true
之前的x项目和之后的y项目(邻居):
// (_id fields omitted)
{ "msg": "hello 1" }
{ "msg": "hello 2" }
{ "msg": "hello 3", "lastseen": true }
{ "msg": "hello 4" }
{ "msg": "hello 5" }
例如,如果我使用x=1
和y=1
进行查询,结果应为:
// (_id fields omitted)
{ "msg": "hello 2" }
{ "msg": "hello 3", "lastseen": true }
{ "msg": "hello 4" }
我在mongodb中有什么选择才能实现这一目标?
答案 0 :(得分:1)
在客户端实现具有多个查询的逻辑必须更简单。假设您的文档是由_id订购的:
findOne({"lastseen":true})
find({_id: {$lt: <_id from the previous query>}}).sort({_id:-1}).limit(1)
find({_id: {$gt: <_id from the first query>}}).sort({_id:1}).limit(1)
我可以想象在单个查询中执行此操作的唯一方法是将文档分组到数组中,然后将$indexOfArray与$slice结合使用:
db.collection.aggregate([
// ensure lastseen is present to calculate index properly
{ $addFields: {lastseen: { $ifNull: [ "$lastseen", false ] } } },
// get all documents into array
{ $group: { _id:null, docs: { $push:"$$ROOT" } } },
// get index of first matched document
{ $project: { docs:1, match: { $indexOfArray: [ "$docs.lastseen", true ] } } },
// slice the array
{ $project: { docs: { $slice: [ "$docs", { $subtract: [ "$match", 1 ] } , 3 ] } } },
// remove added lastseen
{ $project: { docs:
{ $map: {
input: "$docs",
as: "doc",
in: { $cond: {
if: "$$doc.lastseen",
then: "$$doc",
else: { $arrayToObject: { $filter: {
input: { $objectToArray: "$$doc" },
as: "field",
cond: { $ne: [ "$$field.k", "lastseen" ] }
} } }
} }
} }
} },
// un-group documents from the array
{ $unwind: "$docs" },
{ $replaceRoot: {newRoot:"$docs"}}
]);
但我怀疑这种查询的效率。
答案 1 :(得分:0)
答案非常短,您可以使用skip()跳过您想要的数量 //(省略_id字段)
{&#34; msg&#34;:&#34;你好1&#34; }
{&#34; msg&#34;:&#34;你好2&#34; }`
{&#34; msg&#34;:&#34; hello 3&#34;,&#34; lastseen&#34;:true}
{&#34; msg&#34;:&#34;你好4&#34; }
{&#34; msg&#34;:&#34;你好5&#34; }
<强>命令:强>
db.collection.find({},{_ ID:0})。跳过(1)