Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB query to find property of first element of array

Tags:

mongodb

I have the following data in MongoDB (simplified for what is necessary to my question).

{
    _id: 0,
    actions: [
        {
            type: "insert",
            data: "abc, quite possibly very very large"
        }
    ]
}
{
    _id: 1,
    actions: [
        {
            type: "update",
            data: "def"
        },{
            type: "delete",
            data: "ghi"
        }
    ]
}

What I would like is to find the first action type for each document, e.g.

{_id:0, first_action_type:"insert"}
{_id:1, first_action_type:"update"}

(It's fine if the data structured differently, but I need those values present, somehow.)

EDIT: I've tried db.collection.find({}, {'actions.action_type':1}), but obviously that returns all elements of the actions array.

NoSQL is quite new to me. Before, I would have stored all this in two tables in a relational database and done something like SELECT id, (SELECT type FROM action WHERE document_id = d.id ORDER BY seq LIMIT 1) action_type FROM document d.

like image 414
Paul Draper Avatar asked Oct 04 '13 06:10

Paul Draper


3 Answers

You can use $slice operator in projection. (but for what you do i am not sure that the order of the array remain the same when you update it. Just to keep in mind))

db.collection.find({},{'actions':{$slice:1},'actions.type':1})
like image 148
attish Avatar answered Oct 16 '22 17:10

attish


You can also use the Aggregation Pipeline introduced in version 2.2:

db.collection.aggregate([
  { $unwind: '$actions' },
  { $group: { _id: "$_id", first_action_type: { $first: "$actions.type" } } }
])
like image 1
Agis Avatar answered Oct 16 '22 16:10

Agis


Using the $arrayElemAt operator is actually the most elegant way, although the syntax may be unintuitive:

db.collection.aggregate([
  { $project: {first_action_type: {$arrayElemAt: ["$actions.type", 0]}
])
like image 1
scribu Avatar answered Oct 16 '22 15:10

scribu