Kamalpreet
Kamalpreet

Reputation: 1143

Querying data from Mongo collection using javascript

This is the first time I am using mongo for a meteor project, which is to help collaborate a group of users to read the holy scriptures. The data structure for the collection looks as follows:

//collection is named as 'logs'
[
    {
        _id: someObjectId,
        startPage: 1,
        finishPage: 4,
        status: 'in progress',
        userId: someUserId1
    },
    {
        _id: someObjectId,
        startPage: 5,
        finishPage: 10,
        status: 'done',
        userId: someUserId2
    }
    //.... and so on and normally two users wont read the same page.
]

I am trying to figure out the following:

Now due to my limited knowledge of mongo I'm stuck at this point. I have been looking at various solutions but not sure which one would be the right fit:

  1. Aggregation (but I'm unclear as to how I would achieve the required data)
  2. MapReduce (should this be used every time when a new log is added or MapReduce is only meant to run as a batch job)
  3. Create a new separate collection that would hold all the tracking data and update it every time a log is either added or updated

e.g.

 [
    {
        page: 1,
        inProgress: 0, //users would normally not read the same page twice but they may
        done: 1
    },
    {
        page: 2,
        inProgress: 1, //users would normally not read the same page twice but they may
        done: 0
    }
]

I would be really grateful if somebody could provide some insight into this and preferred way of doing it. It may be obvious but I'm finding it a bit hard. Thanks.

Upvotes: 1

Views: 56

Answers (1)

Kevin Smith
Kevin Smith

Reputation: 14436

I'd try to model your documents as per the usage you're trying to achieve, If you split up the logs in to just pages read then you can do a simple group by.

So say we change your models in to the following:

[{
    _id: new ObjectId(),
    pageNumber: 1,
    status: 'in progress',
    userId: 1
},
{
    _id: new ObjectId(),
    pageNumber: 2,
    status: 'in progress',
    userId: 1
},
{
    _id: new ObjectId(),
    pageNumber: 3,
    status: 'in progress',
    userId: 1
},
{
    _id: new ObjectId(),
    pageNumber: 4,
    status: 'in progress',
    userId: 1
},
{
    _id: new ObjectId(),
    pageNumber: 5,
    status: 'in progress',
    userId: 1
},
{
    _id: new ObjectId(),
    pageNumber: 6,
    status: 'done',
    userId: 2
},
{
    _id: new ObjectId(),
    pageNumber: 7,
    status: 'done',
    userId: 2
},
{
    _id: new ObjectId(),
    pageNumber: 8,
    status: 'done',
    userId: 2
},
{
    _id: new ObjectId(),
    pageNumber: 9,
    status: 'done',
    userId: 2
},
{
    _id: new ObjectId(),
    pageNumber: 10,
    status: 'done',
    userId: 2
},
{
    _id: new ObjectId(),
    pageNumber: 9,
    status: 'done',
    userId: 1
},
{
    _id: new ObjectId(),
    pageNumber: 10,
    status: 'done',
    userId: 1
}]

Then we can run the following aggregation query:

> db.logs.aggregate([ {$group: { _id: { "pageNumber" : "$pageNumber", "status" : "$status"}, count : {$sum : 1}}} ]).pretty()
{ "_id" : { "pageNumber" : 8, "status" : "done" }, "count" : 1 }
{ "_id" : { "pageNumber" : 7, "status" : "done" }, "count" : 1 }
{ "_id" : { "pageNumber" : 6, "status" : "done" }, "count" : 1 }
{ "_id" : { "pageNumber" : 4, "status" : "in progress" }, "count" : 1 }
{ "_id" : { "pageNumber" : 9, "status" : "done" }, "count" : 2 }
{ "_id" : { "pageNumber" : 3, "status" : "in progress" }, "count" : 1 }
{ "_id" : { "pageNumber" : 10, "status" : "done" }, "count" : 2 }
{ "_id" : { "pageNumber" : 2, "status" : "in progress" }, "count" : 1 }
{ "_id" : { "pageNumber" : 5, "status" : "in progress" }, "count" : 1 }
{ "_id" : { "pageNumber" : 1, "status" : "in progress" }, "count" : 1 }

Upvotes: 2

Related Questions