如何在MongoDB中查询数组中的单个embedded式文档?

我正在试图查询MongoDB中的数组中的单个embedded式文档。 我不知道我做错了什么。 以编程方式,我将查询此文档,并将新的embedded式文档插入到当前空trips数组中。

 { "_id" : ObjectId("564b3300953d9d51429163c3"), "agency_key" : "DDOT", "routes" : [ { "route_id" : "6165", "route_type" : "3", "trips" : [ ] }, { "route_id" : "6170", "route_type" : "3", "trips" : [ ] }, ... ] } 

以下查询 – 我运行在mongo shell – 返回空:

 db.tm_routes.find( { routes : {$elemMatch: { route_id:6165 } } } ).pretty(); db.tm_routes.find( { routes : {$elemMatch: { route_id:6165,route_type:3 } } } ).pretty(); db.tm_routes.find({'routes.route_id':6165}).pretty() 

还有db.tm_routes.find({'routes.route_id':6165}).count()0

以下查询返回数组中的每个文档

 db.tm_routes.find({'routes.route_id':'6165'}).pretty(); { "_id" : ObjectId("564b3300953d9d51429163c3"), "agency_key" : "DDOT", "routes" : [ { "route_id" : "6165", "route_type" : "3", "trips" : [ ] }, { "route_id" : "6170", "route_type" : "3", "trips" : [ ] }, ... ]} 

但是db.tm_routes.find({'routes.route_id':'6165'}).count()返回1。

最后,这里是我如何插入数据的第一个地方 – 在Node.JS-:

 async.waterfall([ ... //RETRIEVE ALL ROUTEIDS FOR EVERY AGENCY function(agencyKeys, callback) { var routeIds = []; var routesArr = []; var routes = db.collection('routes'); //CALL GETROUTES FUNCTION FOR EVERY AGENCY async.map(agencyKeys, getRoutes, function(err, results){ if (err) throw err; else { callback(null, results); } }); //GET ROUTE IDS function getRoutes(agencyKey, callback){ var cursor = routes.find({agency_key:agencyKey}); cursor.toArray(function(err, docs){ if(err) throw err; for(i in docs){ routeIds.push(docs[i].route_id); var routeObj = { route_id:docs[i].route_id, route_type:docs[i].route_type, trips:[] }; routesArr.push(routeObj); /* I TRIED 3 DIFFERENT WAYS TO PUSH DATA //1-> collection.update({agency_key:agencyKey}, {$push:{"routes":{ 'route_id':docs[i].route_id, 'route_type':docs[i].route_type, 'trips':[] }}}); //2-> collection.update({agency_key:agencyKey}, {$push:{"routes":routeObj}}); */ } // 3-> collection.update({agency_key:agencyKey}, {$push:{routes:{$each:routesArr}}}); callback(null, routeIds); }); }; }, ... var collection = newCollection(db, 'tm_routes',[]); function newCollection(db, name, options){ var collection = db.collection(name); if (collection){ collection.drop(); } db.createCollection(name, options); return db.collection(name); } 

注意:我没有使用mongoose,如果可能的话,不想使用。

梅利斯,

我明白你在问什么,你需要的是帮助你理解在MongoDB中存储的东西。 事情要了解:

  • document是MongoDB的基本数据单元,可以粗略地与关系数据库中的row进行比较。
  • 一个collection可以被认为是一个具有dynamic模式的表格

因此, documents存储在collections 。每个文档都有一个特殊的_id ,这在集合中是唯一的。 以下格式显示给我们的是一个 document

 { "_id" : ObjectId("564b3300953d9d51429163c3"), "agency_key" : "DDOT", "routes" : [ { "route_id" : "6165", "route_type" : "3", "trips" : [ ] }, { "route_id" : "6170", "route_type" : "3", "trips" : [ ] }, ... ]} 

如果您在tm_routes集合中运行queryfind()将返回与该查询匹配的collection中的每个document 。 因此,当你运行查询db.tm_routes.find({'routes.route_id':'6165'}).pretty(); 它将返回与查询匹配的整个文档。 所以这个说法是错误的:

以下查询返回数组中的每个文档

如果您需要在该文档中查找特定的路由,并根据您的用途返回该路由,因为它是一个数组,您可能必须使用$ -Positional运算符或聚合框架 。