猫鼬人口无视选择

时间:2013-11-14 16:50:32

标签: node.js mongodb mongoose

我无法理解猫鼬的人口逻辑。

我有一个UserSchema,它包含一系列文章。

articles: {
    type: [{
        article: {
            type: Schema.Types.ObjectId,
            ref: "Article"
        },
        read: Boolean,
        starred: Boolean
    }]
},

文章存储在单独的集合中。现在我想查找用户的所有已加星标的文章,填充这些文章,按发布日期对其进行排序并对结果进行分页。

User.findOne({_id: user.id, "articles.starred": true}).populate({path: "articles.article", options: {sort: {"published": -1}, skip: 20, limit: 20}}).exec(function(err, _user) {
    callback(_user);
});

问题是人口已经完成,但选项完全被忽略了。

以下是用户和文章的外观:

用户:

{
    "__v" : 0,
    "_id" : ObjectId("5284ef45fe46a55194000003"),
    "articles" : [ 
        {
            "article" : ObjectId("5284ef52fe46a55194000005"),
            "read" : true,
            "starred" : true,
            "_id" : ObjectId("5284ef53fe46a55194000ae1")
        }
    ],
    "categories" : [ 
        {
            "_id" : ObjectId("5284ef52fe46a55194000004"),
            "feeds" : [ 
                {
                    "url" : "http://feeds.dzone.com/zones/dotnet",
                    "name" : ".NET Zone - Community for .NET developers everywhere"
                }
            ],
            "name" : ".NET"
        }
    ],
    "email" : "xxxx",
    "google" : {},
    "name" : "xxxx",
    "provider" : "xxxx"
}

文章:

{
    "author" : "Michael Hession",
    "title" : "You'll Never Want to Put Away This Elegant Pour-Over Coffee Dripper",
    "published" : ISODate("2013-06-13T16:38:00.000Z"),
    "link" : "http://gizmodo.com/youll-never-want-to-put-away-this-elegant-pour-over-co-513136433",
    "feed" : {
        "title" : "Gizmodo",
        "link" : {
            "html" : "http://gizmodo.com",
            "xml" : "feed/http://feeds.gawker.com/gizmodo/excerpts.xml"
        }
    },
    "summary" : "html content",
    "_id" : ObjectId("5284ef52fe46a55194000005"),
    "__v" : 0
}

1 个答案:

答案 0 :(得分:1)

由于我找不到解决方案,我做了一个解决方法。

User.findOne({_id: user.id, "articles.starred": false}).populate({path: "articles.article"}).exec(function(err, _user) {
    if (!err && _user) {
        var articles = _user.articles.sort(function(art1, art2) {
            d1 = art1.article.published;
            d2 = art2.article.published;

            if (d1 > d2) return -1;
            if (d1 < d2) return 1;

            return 0;
        }).slice(skip, skip + 20);

        callback(articles);
    } else {
        callback([]);
    };
});

如果有人想出更好的主意,请告诉我。

更新

经过大量研究后,我改变了我的UserSchema并找到了一个更好的解决方案,它使用了类似于mongoose API文档中解释的人口。

UserSchema:

var UserSchema = new Schema({
    name: {
        type: String,
        default: ""
    },
    email: {
        type: String,
        default: ""
    },
    provider: {
        type: String,
        default: ""
    },
    categories: {
        type: [Category]
    },
    articles: {
        read: [{type: Schema.Types.ObjectId, ref: "Article"}],
        unread: [{type: Schema.Types.ObjectId, ref: "Article"}],
        starred: [{type: Schema.Types.ObjectId, ref: "Article"}]
    },
    google: {},
    facebook: {},
    twitter: {}
});

getFeed:

User.findById(user.id, "articles." + params.state, function(err, _user) {
    User.populate(_user, {path: "articles." + params.state, options: {sort: {"published": -1}, skip: params.skip, limit: 20}}, function(_err, __user) {
        if (!_err && __user) {
            callback(__user.articles[params.state]);
        } else {
            callback([]);
        };
    });
});