Pregunta

I have just started to play with MongoDB and have some questions about how I update my documents in the database. I insert two documents in my db with

db.userscores.insert({name: 'John Doe', email: 'john.doe@mail.com', levels : [{level: 1, hiscores: [90, 40, 25], achivements: ['capture the flag', 'it can only be one', 'apple collector', 'level complete']}, {level: 2, hiscores: [30, 25], achivements: ['level complete']}, {level: 3, hiscores: [], achivements: []}]});
db.userscores.insert({name: 'Jane Doe', email: 'jane.doe@mail.com', levels : [{level: 1, hiscores: [150, 90], achivements: ['Master of the universe', 'capture the flag', 'it can only be one', 'apple collector', 'level complete']}]});

I check if my inserting worked with the find() command and it looks ok.

db.userscores.find().pretty();
{
        "_id" : ObjectId("5358b47ab826096525d0ec98"),
        "name" : "John Doe",
        "email" : "john.doe@mail.com",
        "levels" : [
                {
                        "level" : 1,
                        "hiscores" : [
                                90,
                                40,
                                25
                        ],
                        "achivements" : [
                                "capture the flag",
                                "it can only be one",
                                "apple collector",
                                "level complete"
                        ]
                },
                {
                        "level" : 2,
                        "hiscores" : [
                                30,
                                25
                        ],
                        "achivements" : [
                                "level complete"
                        ]
                },
                {
                        "level" : 3,
                        "hiscores" : [ ],
                        "achivements" : [ ]
                }
        ]
}
{
        "_id" : ObjectId("5358b47ab826096525d0ec99"),
        "name" : "Jane Doe",
        "email" : "jane.doe@mail.com",
        "levels" : [
                {
                        "level" : 1,
                        "hiscores" : [
                                150,
                                90
                        ],
                        "achivements" : [
                                "Master of the universe",
                                "capture the flag",
                                "it can only be one",
                                "apple collector",
                                "level complete"
                        ]
                }
        ]
}

How can I add/update data to my userscores? Lets say I want to add a hiscore to user John Doe on level 1. How do I insert the hiscore 75 and still have the hiscore array sorted? Can I limit the number of hiscores so the array only contains 3 elements? I have tried with

db.userscores.aggregate(
    // Initial document match (uses name, if a suitable one is available)
    { $match: {
        name : 'John Doe'
    }},

    // Expand the levels array into a stream of documents
    { $unwind: '$levels' },

    // Filter to 'level 1' scores 
    { $match: {
        'levels.level': 1
    }},

    // Add score 75 with cap/limit of 3 elements
    { $push: {
        'levels.hiscore':{$each [75], $slice:-3}
    }}
);

but it wont work, the error I get is "SyntaxError: Unexpected token [".

And also, how do I get the 10 highest score from all users on level 1 for example? Is my document scheme ok or can I use a better scheme for storing users hiscores and achivements on diffrent levels for my game? Is there any downsides on quering or performance using they scheme above?

¿Fue útil?

Solución

You can add the score with this statement:

db.userscores.update(
  { "name": "John Doe", "levels.level": 1 }, 
  { "$push": { "levels.$.hiscores": 75 } } )

This will not sort the array as this is only supported if your array elements are documents.

In MongoDB 2.6 you can use sorting also for non-document arrays:

db.userscores.update(
  { "name": "John Doe", "levels.level": 1 }, 
  { "$push": { "levels.$.hiscores": { $each: [ 75 ], $sort: -1, $slice: 3 } } } )
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top