0

I have documents in games collection.Each document is responsible for holding the data that requires to run the game. Here's my document structure

{
    _id: 'xxx',
    players: [
            user:{} // Meteor.users object
            hand:[] //array
            scores:[]
            calls:[]
        ],
    table:[],
    status: 'some string'


}

Basically this is a structure of my card game(call-bridge). Now what I want for the publication is that the player will have his hand data in his browser( minimongo ) along with other players user, scores, calls fields. So the subscription that goes down to the browser will be like this.

{
    _id: 'xxx',
    players: [
            {
                user:{} // Meteor.users object
                hand:[] //array
                scores:[]
                calls:[]
            },
            {
                user:{} // Meteor.users object
                scores:[]
                calls:[]
            },
            //  2 more player's data, similar to 2nd player's data

        ],
    table:[],
    status: 'some string'


}

players.user object has an _id property which differentiates the user. and in the meteor publish method, we have access to this.userId which returns the userId who is requesting the data.It means I want the nested hand array of that user whose _id matches with this.userId. I hope this explanations help you write more accurate solution.

2 Answers 2

1

What you need to do is "normalize" your collection. Instead of having hand,scores, calls in the players field in the Games collection, what you can do is create a separate collection to hold that data and use the user _id as the "Key" then only reference the user _id in the players field. For example.

Create a GameStats collection(or whichever name you want)

    {
_id: '2wiowew',
userId: 1,
hand:[],
scores:[],
calls:[],
}

Then in the Games collection

{
    _id: 'xxx',
    players: [userId],
    table:[],
    status: 'some string'


}

So if you want to get the content of the current user requesting the data

GameStats.find({userId: this.userId}).hand

EDIT

They do encourage denormalization in certain situations, but in the code you posted above, array is not going to work. Here is an example from the mongoDB docs.

{
_id: ObjectId("5099803df3f4948bd2f98391"),
name: { first: "Alan", last: "Turing" },
birth: new Date('Jun 23, 1912'),
death: new Date('Jun 07, 1954'),
contribs: [ "Turing machine", "Turing test", "Turingery" ],
views : NumberLong(1250000)
}
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for your suggestion. As MongoDB encourages denormalization, i'm looking for answer than matches with my structure. :)
0

To get a specific property from an array element you may write something as in the below line db.games.aggregate([{$unwind:"$players"},{$project:{"players.scores":1}}]); this gives us only the id and scores fields

1 Comment

i don't think aggregation would work for my case. i need to return a find cursor for meteor publish

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.