在get请求Node.js中链接收集方法/ promise

时间:2016-02-19 20:10:40

标签: javascript node.js mongodb

我正在尝试使用find()方法从MongoDB数据库中获取一些数据,只返回包含指定“room”的文档。然后,我想返回找到的房间数组的所有不同值,其键等于“品种”。我用两种不同的方式尝试过这种方法,我的方法可能会让步。第一种方法是链接集合方法find()和distinct()。这不起作用:

这就是plantList集合的样子:

[
{
    "_id": {
        "$oid": "56c11a761b0e60030043cbae"
    },
    "date added": "10/21/2016",
    "variety": "Lettuce",
    "room": "Room 1"
},
{
    "_id": {
        "$oid": "56c11a761b0e60030043cbaf"
    },
    "date added": "10/21/2015",
    "variety": "Tomatoes",
    "room": "Room 2"
}
]

server.js

//plantList = db collection
var mongojs = require('mongojs');
var MongoClient = require("mongodb").MongoClient;

MongoClient.connect(process.env.MONGOLAB_URI, function(err, db) {
var plantList = db.collection("plantList");

app.get('/gettypesbyroom/:room', function(req, res) {
       var roomReq = req.params.room;
        plantList
        .find({"room":roomReq})
            .toArray()
                .distinct("variety", function(err, docs) {
                    if (err) throw err;
                    res.json(docs);
                });
});
});

我的第二种方法是使用.then()链接promises并使用underscore.js选择房间数组的键(也不起作用):

app.get('/gettypesbyroom/:room', function(req, res) {
       var roomReq = req.params.room;
        plantList
        .find({"room":roomReq})
            .toArray(function(err, docs) {
                if (err) throw err;
                return docs;
            }).then(function(docs) {
            _.keys(docs, function(docs) { return docs.variety; });
        }).then(function(varieties) {
            res.json(varieties); //not inside scope of .get function?
        });
});

我能做些不同的事情来完成这些工作,或者完全采用不同的方法吗?

2 个答案:

答案 0 :(得分:1)

尝试在没有toArray的情况下调用它:

//plantList = db collection
app.get('/gettypesbyroom/:room', function(req, res) {
  var roomReq = req.params.room;

  plantList
  .find({ room: roomReq })
  .distinct('type', function(err, docs) {
    if (err) throw err;
    res.json(docs);
  });
});

请参阅How Do I Query For Distinct Values in Mongoose

答案 1 :(得分:0)

你可以再做两种方式。一个是通过投影操作员使其更容易 - 只需投射您需要的内容。例如。如果你有一个看起来像这样的文件:

{
  room: 123,
  type: 'soundproof_room',
  other: 'stuff'
}

...您可以使用这样的查询进行投影,只需选择type

即可
db.rooms.find({ room: room }, { type: 1 }).toArray();

那会给你一个像这样的对象数组:

let roomTypes = [{type: 'soundproof_room'}, {type: 'windy_room'}, {type: 'soundproof_room'}, {type: 'room without doors'}]

(显然,我正在制作types,我不知道它们到底是什么。)

然后使用简单的地图:

return res.json(
  roomTypes
    // extract the type
    .map(room => room.type)  
    // filter out duplicates
    .filter((type, idx, self) => self.indexOf(type) === idx)
);

(我使用ES6 arrow fn,希望你能读懂,如果没有:babeljs.io/repl /)

要尝试的另一件事是聚合。

db.rooms.aggregate({
  // first find your room
  $match: { room: room }
},
{
  // group by type, basically make distinct types
  $group: {
    _id: '$type',
    count: {$sum: 1} // inc this by 1 for each room of this type
  }
});

那个人会把你送到你的房间,只会给你回复房间的类型和每种类型的计数,作为额外的奖励。

相关问题