Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript MongoDB,使用bigdata的慢速查询_Javascript_Node.js_Mongodb_Mongoose_Gtfs - Fatal编程技术网

Javascript MongoDB,使用bigdata的慢速查询

Javascript MongoDB,使用bigdata的慢速查询,javascript,node.js,mongodb,mongoose,gtfs,Javascript,Node.js,Mongodb,Mongoose,Gtfs,我试图在mongodb中的一个大集合上执行一个查询,实际上该查询由两部分组成,总共需要大约900ms的时间来执行,我需要它更快 这些是集合,停止时间: > db.stoptimes.find().limit(1); { "trip_id": "24893A459B661", "arrival_time": "22:30:00", "departure_time": "22:30:00", "stop_id": "1904", "stop_sequen

我试图在mongodb中的一个大集合上执行一个查询,实际上该查询由两部分组成,总共需要大约900ms的时间来执行,我需要它更快

这些是集合,停止时间

> db.stoptimes.find().limit(1);
{
    "trip_id": "24893A459B661",
    "arrival_time": "22:30:00",
    "departure_time": "22:30:00",
    "stop_id": "1904",
    "stop_sequence": 2,
    "stop_headsign": "",
    "pickup_type": "0",
    "drop_off_type": "0",
    "shape_dist_traveled": "0.88659123054",
    "agency_key": "alamedaoakland-ferry",
    "_id": ObjectId("52b394c680052ea30918fd62")
}
> db.stoptimes.count();
5959551
> db.trips.find().limit(1);
{
    "route_id": "60",
    "service_id": "180A536",
    "trip_id": "23736A180B536",
    "trip_short_name": "",
    "trip_headsign": "San Francisco via Pier 41",
    "direction_id": "",
    "block_id": "282",
    "shape_id": "30",
    "trip_bikes_allowed": "2",
    "agency_key": "alamedaoakland-ferry",
    "_id": ObjectId("52b394c780052ea30918ff34")
}
> db.trips.count();
204884
行程

> db.stoptimes.find().limit(1);
{
    "trip_id": "24893A459B661",
    "arrival_time": "22:30:00",
    "departure_time": "22:30:00",
    "stop_id": "1904",
    "stop_sequence": 2,
    "stop_headsign": "",
    "pickup_type": "0",
    "drop_off_type": "0",
    "shape_dist_traveled": "0.88659123054",
    "agency_key": "alamedaoakland-ferry",
    "_id": ObjectId("52b394c680052ea30918fd62")
}
> db.stoptimes.count();
5959551
> db.trips.find().limit(1);
{
    "route_id": "60",
    "service_id": "180A536",
    "trip_id": "23736A180B536",
    "trip_short_name": "",
    "trip_headsign": "San Francisco via Pier 41",
    "direction_id": "",
    "block_id": "282",
    "shape_id": "30",
    "trip_bikes_allowed": "2",
    "agency_key": "alamedaoakland-ferry",
    "_id": ObjectId("52b394c780052ea30918ff34")
}
> db.trips.count();
204884
我试图在trips集合中查找每个不同的route_id,其中trip_id等于与stoptimes中给定的stop_id匹配的每个trip id

------ stoptimes --- -> ---------- trips -----------------
stop_id1 -> trip_id1 -> trip_id1 -> route_id1 -> route_id1 
         -> trip_id2 -> trip_id2 -> route_id2 -> route_id2
         -> trip_id3 -> trip_id3 -> route_id2
         -> trip_id4 -> trip_id4 -> route_id2
         -> trip_id5 -> trip_id5 -> route_id3 -> route_id3
这是mongodb shell中的查询:

> var tripids = db.stoptimes.aggregate([
... {$match : { 'stop_id' : '1904' }},
... {$project : { '_id' : 0, 'trip_id' : 1 }}
... ]);
> var arr = [];
> for(var i=0; i<tripids.result.length; i++)
... { arr.push(tripids.result[i].trip_id); }
> db.trips.aggregate([
... {$match : { 'trip_id' : {$in : arr}}},
... {$group : {
...  _id : "$route_id", 
...  direction_id : { $first: '$direction_id'}, 
...  shape_id : {$first : '$shape_id'}}}
... ])

看起来您正在对与数组中的任何记录匹配的所有行程(204884次行程)运行聚合方法。如果这是真的,你正在处理大约228条记录/毫秒,这是非常好的

您可以在代码中进行一些明显的优化

除非您有特定的原因,否则永远不要使用i++,始终将其作为++i编写,并将计数放在单独的变量中

var trip_ids_length = trip_ids.length;
for(var i=0;i<trip_ids_length;++i) {
    arr.push(trip_ids[i].trip_id);
}
var跳闸id\u长度=跳闸id.length;

对于(var i=0;i确保在“trips”集合中有一个关于“trip\u id”的索引。 即使使用索引,如果为“arr”提供一长串值,也无法获得最佳性能。“in”运算符很难优化,因为必须查看每个值。例如,如果“arr”数组有10个值,则必须为每个值搜索索引。它基本上看起来像10个子查询

您可以设计模式以避免使用“$in”操作符、查找2个集合和使用聚合框架

我将假设“trip\u id+stop\u id”在“stoptimes”集合中是唯一的,“route\u id”在“trips”集合中是唯一的

让我们去规范化数据。 保留“stoptimes”集合以包含站点的详细信息,但让我们将其中一些信息添加到“trips”集合中:

{
"route_id": "60",
"service_id": "180A536",
"trip_id": "23736A180B536",
"stop_id" : [ 1800, 1830, 1904]   <==============
"trip_short_name": "",
"trip_headsign": "San Francisco via Pier 41",
"direction_id": "",
"block_id": "282",
"shape_id": "30",
"trip_bikes_allowed": "2",
"agency_key": "alamedaoakland-ferry",
"_id": ObjectId("52b394c780052ea30918ff34")
}
使用“stop_id”上的索引,您的查询应该非常快

总之,设计您的架构,使其针对最重要的查询进行优化。如果上述查询是最重要的,则您将受益于新的架构设计。如果这是一个单独的查询,并且您已经针对常见情况进行了优化,则Eric的建议可能会满足您的需要。如果您决定保留聚合框架在解决方案中,您可以评估聚合管道第一步的性能。运行以下命令以确保$match步骤使用索引

db.collection.runCommand("aggregate", {pipeline: YOUR_PIPELINE, explain: true})
db.collection.runCommand("aggregate", {pipeline: YOUR_PIPELINE, explain: true})