[ACCEPTED]-Finding The Next Document in MongoDb-mongodb
It is best to add explicit sort()
criteria if 12 you want a predictable order of results.
Assuming 11 the order you are after is "insertion 10 order" and you are using MongoDB's 9 default generated ObjectIds, then you can 8 query based on the ObjectId:
// Find next product created
db.products.find({_id: {$gt: ObjectId("4fdbaf608b446b0477000142") }}).limit(1)
Note that this 7 example only works because:
- the first four bytes of the ObjectId are calculated from a unix-style timestamp (see: ObjectId Specification)
- a query on
_id
alone will use the default_id
index (sorted by id) to find a match
So really, this 6 implicit sort is the same as:
db.products.find({_id: {$gt: ObjectId("4fdbaf608b446b0477000142" )}}).sort({_id:1}).limit(1);
If you added 5 more criteria to the query to qualify how 4 to find the "next" product (for 3 example, a category
), the query could use a different 2 index and the order may not be as you expect.
You 1 can check index usage with explain().
You can get the items back in insertion 4 order using ObjectId. See: http://www.mongodb.org/display/DOCS/Optimizing+Object+IDs#OptimizingObjectIDs
If you want 3 to get them back in some other order then 2 you will have to define what that order 1 is and store more information in your documents.
Starting in Mongo 5
, it's a perfect use case for 1 the new $setWindowFields
aggregation operator:
// { _id: 1, name: "product 1" }
// { _id: 2, name: "product 2" }
// { _id: 3, name: "product 3" }
db.collection.aggregate([
{ $setWindowFields: {
sortBy: { _id: 1 },
output: { next: { $push: "$$ROOT", window: { documents: [1, 1] } } }
}}
])
// { _id: 1, name: "product 1", next: [{ _id: 2, name: "product 2" }] }
// { _id: 2, name: "product 2", next: [{ _id: 3, name: "product 3" }] }
// { _id: 3, name: "product 3", next: [ ] }
This:
$sort
s documents by their order of insertion using their_id
s (ObjectId
s contain the timestamp of insertion):sortBy: { _id: 1 }
- adds the
next
field in each document (output: { running: { ... }}
)- by
$push
ing the whole document$$ROOT
($push: "$$ROOT"
) - on a specified span of documents (the
window
) which is in this case is a range of only the next document document:window: { documents: [1, 1] }
.
- by
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.