Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

insert to specific index for mongo array

Tags:

mongodb

Mongo supports arrays of documents inside documents. For example, something like

{_id: 10, "coll": [1, 2, 3] }

Now, imagine I wanted to insert an arbitrary value at an arbitrary index

{_id: 10, "coll": [1, {name: 'new val'}, 2, 3] }

I know you can update values in place with $ and $set, but nothing for insertion. it kind of sucks to have to replace the entire array just for inserting at a specific index.

like image 882
Matt Briggs Avatar asked Jun 20 '11 17:06

Matt Briggs


People also ask

How to index an array in MongoDB?

To index a field that holds an array value, MongoDB creates an index key for each element in the array. These multikey indexes support efficient queries against array fields. Multikey indexes can be constructed over arrays that hold both scalar values 1 (e.g. strings, numbers) and nested documents. Thank you.

How do I create a compound Index in MongoDB?

If the keys document specifies more than one field, then createIndex () creates a compound index. The following example creates a compound index on the orderDate field (in ascending order) and the zipcode field (in descending order.) Changed in version 4.4: Starting in MongoDB 4.4, compound indexes can include a single hashed field.

How do I create a wildcard Index in MongoDB?

MongoDB supports several different index types including text, geospatial, and hashed indexes. See index types for more information. To create a wildcard index on all fields and subfields in a document, specify { "$**" : 1 } as the index key. You cannot specify a descending index key when creating a wildcard index.

How do I push an element to an array in MongoDB?

MongoDB must be properly installed and configured in order to add elements to an array in MongoDB. A basic understanding of how arrays functions. This section will explain how to push an element to an array with a $push operator, such as an update operation. First, create a sample dataset, with animals, as follows: ... });


2 Answers

Starting with version 2.6 you finally can do this. You have to use $position operator. For your particular example:

db.students.update(
  { _id: 10},
  { $push: {
     coll: {
       $each: [ {name: 'new val'} ],
       $position: 1
     }
  }}
)
like image 148
Salvador Dali Avatar answered Oct 19 '22 04:10

Salvador Dali


The following will do the trick:

var insertPosition = 1;
var newItem = {name: 'new val'};

db.myCollection.find({_id: 10}).forEach(function(item)
{
    item.coll = item.coll.slice(0, insertPosition).concat(newItem, item.coll.slice(insertPosition));
    db.myCollection.save(item);
});

If the insertPosition is variable (i.e., you don't know exactly where you want to insert it, but you know you want to insert it after the item with name = "foo", just add a for() loop before the item.coll = assignment to find the insertPosition (and add 1 to it, since you want to insert it AFTER name = "foo".

like image 20
Michael Moussa Avatar answered Oct 19 '22 04:10

Michael Moussa