Reputation: 777
So every user has 0-3 items in the database. I don't have their indexes, I sort them by creation date, from oldest to youngest. I was wondering if it is possible to get the element from result array by its index by native mongo/mongoose tools.
For example I have these 3 documents in DB for user theguy
:
{ "_id" : 1, "name" : "theguy", otherdata: ["data 1", "data 2"] }
{ "_id" : 10, "name" : "theguy", otherdata: ["data 1", "data 2"] }
{ "_id" : 333, "name" : "theguy", otherdata: ["data 1", "data 2"] }
_id
will be ObjectId
Then user will try to get some data. He inputs a number in the range from 1 to 3. There can be 0, 1, 2 or 3 entries in database under his name. The example above displays the situation when user has all 3 entries filled. But user doesn't care about all of them right now, he entered the index, he needs only second result out of these 3.
What works for me right now is this:
//user defined the index
index = 2;
//search all docs by this user, but get only ids
let usrlist = await User.find({"name": name}).distinct('_id');
//based on the ids array we can now request exact second document from the database:
//usrlist[index-1] or usrlist[1]
let exactusr = await User.findOne({"_id": usrlist[index-1]});
So the result for exactusr
will be:
{ "_id" : 10, "name" : "theguy", otherdata: ["data 1", "data 2"] }
I try to minimize the load by getting only ids, instead of all 3 documents at once. Now the thing is, well, this doesn't look "nice". Getting an array of _id
to create another query based on that doesn't seem optimal. And at the end, I don't even know what is better: to do 2 queries(as above) or do 1 query for all user documents and choose the one user needs by index. Documents may be kind of big, containing up to 12000 characters each.
So looking for native ways I found $slice
, but I don't think it works with the result array, or I don't understand how.
My attempt of using $slice
:
index = 2;
usr = await User.find({"name": name}, {$slice: [index-1, 1]});
Result:
[ {"_id" : 1}, {"_id" : 10}, {"_id" : 333} ]
Expected result:
{ "_id" : 10, "name" : "theguy", otherdata: ["data 1", "data 2"] }
Any ideas? Or other methods that I could make this work?
Upvotes: 2
Views: 102
Reputation: 812
I created a collection called "sample" and inserted the sample data that you provided.
db.sample.aggregate([{$match : {"name": "theguy"}}]);
{ "_id" : 1, "name" : "theguy", "otherdata" : [ "data 1", "data 2" ] }
{ "_id" : 10, "name" : "theguy", "otherdata" : [ "data 1", "data 2" ] }
{ "_id" : 333, "name" : "theguy", "otherdata" : [ "data 1", "data 2" ] }
Initialize a variable index : var index=1;
Now if we consider the above data, the indexes of the three rows would be 0,1,2. If I want to retrieve the 2nd row with _id : 10
, then the index is supposed to be 1. In that case, the aggregate query would look like :
db.sample.aggregate([
{ $match : {"name": "theguy"}},
{ $skip : index},
{ $limit : 1 }
]);
In case you want your index value to mean the position i.e. in this case the position is 2, then modify the query like :
var index=2;
db.sample.aggregate([
{ $match : {"name": "theguy"}},
{ $skip : index-1},
{ $limit : 1 }
]);
Try this solution & let us know, if it worked for you!
Upvotes: 1