0

Question: How do I insert an array of simple strings as new documents with a single call? I don't want to convert it before. I am looking for some mongo magic here. The $push, $each things don't seem to work for insertions.

var newTags = [];
newTags.push("tagA");
newTags.push("tagB");

// with this lodash conversion the batch insertion works fine.
// ["tagA", "tagB"] -> [{name: "tagA", name: "tagB"}]
// newTags = _.map(newTags, function(key) {return {'name': key}});

db.collection('tags').insert(newTags, {w: 1},  function (err, result) {

});

My definition of 'not working'

Mongo does insert the newTags, but creates a document from each string like this.
I understand why it does it

{
  "_id": "111111116c021a165abcdd16",
  "0": "t",
  "1": "a",
  "2": "g",
  "3": "A"
},
{
  "_id": "111111126c021a165abcdd17",
  "0": "t",
  "1": "a",
  "2": "g",
  "3": "B"
}

but should be

{ 
  "_id": "111111116c021a165abcdd16",
  "name": "tagA"
},
{ 
  "_id": "111111126c021a165abcdd17",
  "name": "tagB"
}
angabriel
  • 4,979
  • 2
  • 35
  • 37
  • Don't think it's possible without any additional code beforehand. – robertklep Dec 27 '13 at 14:07
  • Also thought that by reading the api, but I couldn't believe it. I am afraid the answer is: "No, at the moment it does not seem to be possible". If you post this kind of answer I am going to mark it as answered. I guess I have to do the conversion beforehand, though I am crying about it ;) – angabriel Dec 27 '13 at 14:16
  • 1
    If it is possible in future, i will cry because it make me confusing, and I will cry : – damphat Dec 27 '13 at 14:21
  • Lol @damphat. I dont want this exactly to work, but instead something like this: `.insert({name: {$each: newTags}, ...` – angabriel Dec 27 '13 at 14:23
  • Whats going on internally, I don't know. But it seems either the driver or at the latest the mongodb is smart enough to insert a String scalar like this. – angabriel Dec 27 '13 at 14:34

1 Answers1

2

To my knowledge it's not possible, because for inserting, MongoDB either accepts a single document object, or an array of such objects, but not an array of scalars.

Which IMO makes sense, because how would MongoDB know that you want to map those scalars to a particular field (name, in this case)? That's application logic, not database logic.

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • Thank you for clarification. SO is great, now I'm much more confident that there is no hidden magic when inserting scalars. – angabriel Dec 27 '13 at 14:28
  • and scalar like 'hello' will be convert to new String('hello') before insert? – damphat Dec 27 '13 at 14:29
  • @damphat it's already a string, and it's being treated as an object, hence the strange-looking documents that are being inserted. Similar to this code: `[ 'foo', 'bar' ].forEach(function(doc) { for (var i in doc) { console.log(i, doc[i]) }});` – robertklep Dec 27 '13 at 14:32
  • I think mongodb will store tag as BSON object instead of BSON string. let's test: console.log(new String('foo')) print String {0: "f", 1: "o", 2: "o") – damphat Dec 27 '13 at 14:41
  • @damphat yes, it will eventually end up as a BSON object in the database, that's true. But I think it's the driver that's doing the 'conversion' of string-to-BSON-object. – robertklep Dec 27 '13 at 14:44