按索引从结果数组中获取一个元素

时间:2018-07-12 07:46:02

标签: mongodb mongoose

因此每个用户在数据库中都有0-3个项目。我没有它们的索引,我按创建日期对它们进行了排序,从最早到最小。我想知道是否有可能通过本机mongo / mongoose工具从结果数组中通过其索引获取元素。

例如,我在数据库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将是ObjectId

然后用户将尝试获取一些数据。他输入的数字范围为1到3。在他的名字下,数据库中可以有0、1、2或3个条目。上面的示例显示了当用户填写所有3个条目时的情况。但是用户现在并不关心所有这些,他输入了索引,他只需要这3个结果中的第二个结果。

现在对我有用的是:

//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]});

所以exactusr的结果将是:

{ "_id" : 10, "name" : "theguy", otherdata: ["data 1", "data 2"] }

我尝试通过仅获取ID(而不是一次获取所有3个文档)来最大程度地减少工作量。现在的事情是,这看起来并不“不错”。获取_id数组以基于该查询创建另一个查询似乎不是最佳方法。最后,我什至不知道有什么更好的方法:进行2个查询(如上所述)或对所有用户文档进行1个查询,然后按索引选择一个用户需求。文档可能很大,每个文档最多包含12000个字符。

因此,我在寻找本机的方式找到了$slice,但我认为它不适用于结果数组,或者我不知道该如何使用。

我尝试使用$slice

index = 2;
usr = await User.find({"name": name}, {$slice: [index-1, 1]});

结果:

[ {"_id" : 1}, {"_id" : 10}, {"_id" : 333} ]

预期结果:

{ "_id" : 10, "name" : "theguy", otherdata: ["data 1", "data 2"] }

有什么想法吗?还是我可以进行这项工作的其他方法?

1 个答案:

答案 0 :(得分:1)

我创建了一个名为“样本”的集合,并插入了您提供的样本数据。

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" ] }

初始化变量索引:var index=1;

现在,如果考虑以上数据,三行的索引将为0,1,2。如果我想使用_id : 10检索第二行,则索引应该为1。在这种情况下,聚合查询将类似于:

db.sample.aggregate([
{ $match : {"name": "theguy"}},
{ $skip : index},
{ $limit : 1 }
]);

如果您希望索引值表示位置,即在这种情况下该位置为2,请修改查询,如:

var index=2;
db.sample.aggregate([
{ $match : {"name": "theguy"}},
{ $skip : index-1},
{ $limit : 1 }
]);

尝试此解决方案,让我们知道,如果它对您有用!