如何一次性使用Mango通过ObjectID查找多个MongoDB文档。我目前有一个非阻塞子,我用它来过滤掉在grep语句中不匹配的文档但是想知道是否可以传递ObjectIDs(可能是Mango :: BSON ::的实例数组) ObjectID)到find方法? 我也认为这种方式效率不高,因为大型收藏品的价格会非常高!
@items;
$self->mango->db->collection('items')->find()->all(sub {
my ($collection, $err, $items) = @_;
return $self->render_exception($err) if $err;
my @oids = $self->req->params->param('ids[]');
foreach my $item (@$items) {
push @items, $item if grep (/$item->{_id}/, @oids);
}
$self->render(json => {items => \@items});
});
这个sub位于我的一个Mojolicous控制器中,它响应JSON调用。 我正在使用以下内容:
提前致谢。
更新
我已经应用了Neil的逻辑,现在它运行正常。
my @oids = map { Mango::BSON::ObjectID->new($_) } ($self->req->params->param('ids[]'));
print Dumper(@oids),"\n";
$self->mango->db->collection('items')->find({ "_id" => {'$in' => \@oids} })->all(sub {
my ($collection, $err, $items) = @_;
return $self->render_exception($err) if $err;
print Dumper($items),"\n";
$self->render(json => {items => $items});
});
转储的OID如下:
$VAR1 = bless( {
'oid' => '52faf6de10d041d196cb545b'
}, 'Mango::BSON::ObjectID' );
$VAR2 = bless( {
'oid' => '5300409310d041d196cb545d'
}, 'Mango::BSON::ObjectID' );
找到的对象看起来像这样(取决于你的结构):
$VAR1 = [
{
'_id' => bless( {
'oid' => '52faf6de10d041d196cb545b'
}, 'Mango::BSON::ObjectID' ),
'class' => [
'Sport'
],
'make' => '4321',
'year' => 2012
},
{
'_id' => bless( {
'oid' => '5300409310d041d196cb545d'
}, 'Mango::BSON::ObjectID' ),
'class' => [
'Classic'
],
'make' => '1234',
'year' => 2014
}
]
答案 0 :(得分:1)
您似乎在寻找$in
运营商。因此,而不是循环所有项目以找到与您匹配的项目,而不是在_id
的调用中传递给您的控制器的find()
值:
my @oids = $self->req->params->param('ids[]');
$self->mango->db->collection('items')
->find({ "_id" => { '$in' => \@oids } })->all(sub {
my ($collection, $err, $items) = @_;
return $self->render_exception($err) if $err;
$self->render(json => {items => $items});
});
实际上有一些时间用Mango测试这个并设法得到一个工作案例:
{ "_id" : ObjectId("5345faf8a1f97e61848485e8"), "prerequisites" : [ "a" ] }
{ "_id" : ObjectId("5345fafea1f97e61848485e9"), "prerequisites" : [ "a", "b" ] }
{ "_id" : ObjectId("5345fb02a1f97e61848485ea"), "prerequisites" : [ "a", "c" ] }
然后运行代码:
#!/usr/bin/env perl
use Modern::Perl;
use EV;
use AnyEvent;
use Data::Dumper;
use Mango;
use Mango::BSON::ObjectID;
my $mango = Mango->new();
my $cv = AE::cv;
my $col = $mango->db('test')->collection('courses');
my @oids = (
"5345fafea1f97e61848485e9",
"5345fb02a1f97e61848485ea"
);
@oids = map { Mango::BSON::ObjectID->new($_) } @oids;
$col->find({ '_id' => { '$in' => \@oids } })->all( sub {
my ( $cursor, $err, $docs ) = @_;
$cv->send( Dumper( $docs ) );
});
say $cv->recv;
这样实际上会从示例中选择正确的文档,并且看起来似乎需要以这种方式传递ObjectID值才能匹配。
至少应该有足够的调试来。