1

I am trying to record the id's of the posts that the user has voted on, and I am creating a schema for it like this:

var userSchema = new Schema({
    twittername: String,
    twitterID: Number,
    votedPosts: [{ObjectId : {votetype : Number}} ]
  });

The user gets created perfectly and I want to update the votedPosts attribute whenever the user votes on something so I call :

User.update({twitterID : req.body.userID} , { $push : {votedPosts : {postID : {votetype: newvotetype }}}} ,function (err, user, raw) {
    if (err){ 
        console.log(err);
    }
    else{
        console.log('user ' + user);
    }

});

Unfortunately the outcome is not as I described in my schema, I get this:

  db.users.find().pretty()
    {
        "__v" : 0,
        "_id" : ObjectId("51bf4ef8dbda2f2e0c000001"),
        "twitterID" : 102016704,
        "twittername" : "gorkemyurt",
        "votedPosts" : [
            {
                "_id" : ObjectId("51bf5e48c3ffefe20c000002")
            }
        ]
    }

I am confused by the extra "_id" that mongoose adds in the votedPosts array.. Why cant ObjectId("51bf5e48c3ffefe20c000002") be the key of a key value pair?

4

1 回答 1

7

I think your problem stems from your schema. You should try to define a schema in which the keys are not dynamically changing. MongoDB does not support queries on the keys of documents, just the values.

I think that using a dynamic "ObjectID" as the key in your schema above is leading to weirdness with Mongoose, and causing your issue. But, even if your query were propagated properly to MongoDB, it would still not produce the output you desire. The reason for this is that MongoDB will interpret "postID" as a String, regardless of whether you've defined some postID variable to hold a dynamic value. This is the output if you run the query from the mongo shell, using a variable postID:

> var postID = 1234
> db.users.update( {twitterID : 102016704}, {$push : {votedPosts : {postID : {votetype: "newvotetype" }}}} )
{
    "__v" : 0,
    "_id" : ObjectId("51bf4ef8dbda2f2e0c000001"),
    "twitterID" : 102016704,
    "twittername" : "gorkemyurt",
    "votedPosts" : [
        {
            "postID" : {
                "votetype" : "newvotetype"
            }
        }
    ]
}

I would suggest that you use another schema. The schema I've proposed below involves embedding a second schema into your existing schema. Try something like this:

var votedPost = new Schema({
    postID: ObjectId,
    votetype : Number 
  });

var userSchema = new Schema({
    twittername: String,
    twitterID: Number,
    votedPosts: [votedPost]
  });

This way, you can also query on the postID field, which MongoDB handles very nicely. Does that make sense? :)

于 2013-09-17T19:27:47.153 回答