输出forEach结果在控制台中?

时间:2017-01-18 14:01:34

标签: mongodb mongodb-query aggregation-framework

我在mongo cli上有这个命令,但我没有得到任何结果:

db.files.find({
    state: 4,
    created : {
            '$gte': ISODate("2017-01-18T00:00:00.000Z"),
            '$lte': ISODate("2017-01-19T00:00:00.000Z")
    }
}).forEach( function (o) {
    db.users.find({"id": ObjectId(o.user)},{"username": 1}).pretty();
});

如何输出cli中的用户名?

db.users.find({},{'id':1, 'username':1}).pretty();
{
    "_id" : ObjectId("5489b6abe4b0e66fc6491c85"),
    "username" : "user@domain.tld"
}

db.files.find({ }, {'id': 1, 'user': 1} ).pretty();
{ "_id" : "--M17HJrR1m1svX6GZS-YQ", "user" : "56bfe199fe6cc47d0c2f8781" }
{ "_id" : "--bnG8eJTfiYE08xjDphmQ", "user" : "56c477a9da1173ce065abfbf" }
{ "_id" : "-0G2Q5fQQTCJhqEWjVkQYw", "user" : "57388a9b9ef0e2201245b265" }

2 个答案:

答案 0 :(得分:2)

看到文件集合中的user字段是字符串,而不是ObjectId,您需要创建ObjectId列表,即将user id字符串映射到ObjectId个数组,您可以使用。{/ p>查询users集合

例如,以下内容使用 distinct() 方法在两个集合上使用第二个查询参数来生成可以查询引用的数组。最终结果将打印以控制usernames

var userIds = db.files.distinct("user", {
    "state": 4,
    "created" : {
        "$gte": ISODate("2017-01-18T00:00:00.000Z"),
        "$lte": ISODate("2017-01-19T00:00:00.000Z")
    }
}).map(function(id) { return ObjectId(id); } );
db.users.distinct("username", {"_id": { "$in": userIds } }).forEach(printjson);

如果用户字段是ObjectId,则使用聚合框架的 $lookup 运算符,如下所示:

db.files.aggregate([
    {
        "$match": {
            "state": 4,
            "created": {
                "$gte": ISODate("2017-01-18T00:00:00.000Z"),
                "$lte": ISODate("2017-01-19T00:00:00.000Z")
            }
        }
    },
    {
        "$lookup": {
            "from": "users",
            "localField": "user",
            "foreignField": "_id",
            "as": "userList"
        }
    },
    {
        "$project": {
            "user": {
                "$arrayElemAt": ["$userList", 0]
            }
        }
    },
    {
        "$project": {
            "username": "$user.username"
        }
    }
]).map(function(doc) { return doc.username; }).forEach(printjson);

答案 1 :(得分:0)

不应该是“_id”而不是“id”

db.files.find({
    state: 4,
    created : {
            '$gte': ISODate("2017-01-18T00:00:00.000Z"),
            '$lte': ISODate("2017-01-19T00:00:00.000Z")
    }
}).forEach( function (o) {
    db.users.find({"_id": ObjectId(o.user)},{"username": 1}).pretty();
});

此外,我认为您可以获得所有ID,然后再调用运营商

var userIds = [];
db.files.find({
        state: 4,
        created : {
                '$gte': ISODate("2017-01-18T00:00:00.000Z"),
                '$lte': ISODate("2017-01-19T00:00:00.000Z")
        }
    },{user:1}).forEach( function (o) {
        userIds.push(new ObjectId(o.user));
    });
    db.users.find({"_id": {$in : userIds},{"username": 1}).pretty();
P.S - Chridam方法比任何方法都更有利。