64

I can't save an array of strings into my DB using Mongoose.

(Note all code below is simplified for ease of writing here)

So i declare a variable of a person schema I have:

var newPerson = new Person ({
    tags: req.body.tags
});

The schema itself looks like:

var personSchema = new mongoose.Schema({
  tags: Array
});

And when it comes to saving its just a simple:

newPerson.save(function(err) {
    //basic return of json
});

So using Postman I send in an array in the body - however everytime I check the DB, it just shows one entry with the array as a whole i.e. how I sent it:

enter image description here

Any ideas what extra I'm supposed to do?

userMod2
  • 8,312
  • 13
  • 63
  • 115
  • 3
    Does this work? - `var personSchema = new mongoose.Schema({ tags: [{type: String}] });` – Ash Feb 19 '16 at 16:06
  • What about just: `var personSchema = new mongoose.Schema({ tags: [String] });` – Ash Feb 19 '16 at 16:14
  • Unfortunately not that either – userMod2 Feb 19 '16 at 16:15
  • 1
    Are you sure that `req.body.tags` is an array? try doing - `console.log(typeof req.body.tags)` or `Array.isArray(req.body.tags)` – Ash Feb 19 '16 at 16:20
  • Ahh! - it's a String. Good spot So whats wrong with that in Postman `['people', 'players']`? – userMod2 Feb 19 '16 at 16:23
  • Try see if this work - https://stackoverflow.com/questions/12756688/is-it-possible-to-send-an-array-with-the-postman-chrome-extension - if it does work let me know and I'll write it up in an answer. – Ash Feb 19 '16 at 16:24
  • Not having luck with that at the moment but at least I'm in the right direction. WIll continue searhcing. Thanks for your help! – userMod2 Feb 19 '16 at 16:28
  • Try your initial request with postman but select 'raw' instead of form-data, and then click 'text' and swap it to JSON like in this screenshot - https://imgur.com/4n3Zfep – Ash Feb 19 '16 at 16:30

13 Answers13

149

Write up from my comment:

The way to specify an array of strings in mongoose is like so:

var personSchema = new mongoose.Schema({
tags: [{
    type: String
}]

However, the problem here is most-likely to do with Postman as it is sending the 'array' as a string. You can check this by checking the type of req.body.tags like so:

console.log(typeof req.body.tags)

If this returns a String, make sure to set the content-type in Postman to JSON as seen in this screenshot rather than the default 'form-data' option.

Ash
  • 6,483
  • 7
  • 29
  • 37
  • The issue is with Postman not taking my array as an array but rather a string – userMod2 Feb 19 '16 at 17:07
  • Indeed, hopefully setting the content-type will fix it. You could always pad it within an object and send it as a JSON object. – Ash Feb 19 '16 at 17:10
61
var schema = new Schema({
  name:    String,
  binary:  Buffer,
  living:  Boolean,
  updated: { type: Date, default: Date.now },
  age:     { type: Number, min: 18, max: 65 },
  mixed:   Schema.Types.Mixed,
  _someId: Schema.Types.ObjectId,
  decimal: Schema.Types.Decimal128,
  array: [],
  ofString: [String],
  ofNumber: [Number],
  ofDates: [Date],
  ofBuffer: [Buffer],
  ofBoolean: [Boolean],
  ofMixed: [Schema.Types.Mixed],
  ofObjectId: [Schema.Types.ObjectId],
  ofArrays: [[]],
  ofArrayOfNumbers: [[Number]],
  nested: {
    stuff: { type: String, lowercase: true, trim: true }
  },
  map: Map,
  mapOfString: {
    type: Map,
    of: String
  }
})

// example use

var Thing = mongoose.model('Thing', schema);

var m = new Thing;
m.name = 'Statue of Liberty';
m.age = 125;
m.updated = new Date;
m.binary = Buffer.alloc(0);
m.living = false;
m.mixed = { any: { thing: 'i want' } };
m.markModified('mixed');
m._someId = new mongoose.Types.ObjectId;
m.array.push(1);
m.ofString.push("strings!");
m.ofNumber.unshift(1,2,3,4);
m.ofDates.addToSet(new Date);
m.ofBuffer.pop();
m.ofMixed = [1, [], 'three', { four: 5 }];
m.nested.stuff = 'good';
m.map = new Map([['key', 'value']]);
m.save(callback);
Phonix
  • 2,010
  • 18
  • 27
14
  1. On Schema:
    ( Since you have mentioned in the problem that it is an array of strings )
var personSchema = new mongoose.Schema({
  tags:{
     type:[String],
     required: true
  }
}); 
  1. On Postman:
{
  "tags": ["css", "javascript", "mongoose", "node"]
}
  1. On MongoDB
{
  "tags":["css", "javascript", "mongoose", "node"]
}

Similarly, you can create other types of primitive arrays and document arrays in the mongoose schema as:

({
  toys: [ToySchema],
  buffers: [Buffer],
  strings: [String],
  numbers: [Number]
  // ... etc
});
Dharman
  • 30,962
  • 25
  • 85
  • 135
Madhawa Jayagoda
  • 347
  • 4
  • 14
10

Try changing the schema to

var personSchema = new mongoose.Schema({
  tags: [{type: String}]
});

or you can use Mixed type

var personSchema = new mongoose.Schema({
  tags: mongoose.Schema.Types.Mixed
});

EDIT

i think the problem is with assignment. Use:

person.tags.push("string to push");
Gurbakhshish Singh
  • 1,034
  • 1
  • 10
  • 25
4
  1. On Schema

    techs: Array

  2. On Postman

    "techs": ["express","rect","html","css","scss"]

  3. On DB (MongoDB)

    "techs" : [ "epxress", "rect", "html", "css", "scss" ]

U.A
  • 2,991
  • 3
  • 24
  • 36
2
var personSchema = new mongoose.Schema({
  tags: [{type: String}]
});

Use this in the schema.

Saving the Array:

var etc = new modename({yourprimaryid: primaryid});
                        for (var i = 0; i < tag.length; i++) {
                            etc.tag.push(tag[i]);
                        }
                        etc.save(function(err) {
                          //whatever you want here
                        }
Gandalf the White
  • 2,415
  • 2
  • 18
  • 39
2

Define a Schema:

const schema = new Schema({
  name: { type: String, required: true },
  tags: [String]
});

In postman add each element separately using the array syntax below

name:Thing
tags[]:task
tags[]:other
tags[]:thing

Return Data:

{
    "__v": 0,
    "name": "Thing",
    "_id": "5a96e8d0c7b7d1323c677b33",
    "tags": [
        "task",
        "other",
        "thing"
    ]
}
Sigkill9
  • 41
  • 6
2

this will also work

var personSchema = new mongoose.Schema({
    tags: {
        type: [String], default: []
    }
});
Ratan Uday Kumar
  • 5,738
  • 6
  • 35
  • 54
2

I had a simialr problem, In the model, do this :

tags : {[String], default: undefined}

So that it defaults to undefined unstead of an empty array, and instead of this:

const person = new Person({
    tags : req.body.tags
});

Do this :

const person = new Person();
person.tags = req.body.tags;
Ilyes42
  • 21
  • 1
  • 2
2

My requirement; ingredients: Type Array of Strings

Solution:

ingredients: {
    type: [String],
  },
dafydd j
  • 31
  • 2
1

Firstly, as many people have noted, the schema needs to change to indicate that the tags field is intended to hold an array of strings, and not just a single one. So that needs to change to:

var personSchema = new mongoose.Schema({
  tags: [String]
});

The other thing you need to keep in mind (and which caused me a lot of trouble), is that when saving, make sure to use a fresh array for the tags field. For example, this won't work:

person.tags[0] = "new tag";
person.save();

Instead, you need to do something like:

person.tags = person.tags.slice(); // Clone the tags array
person.tags[0] = "new tag";
person.save();

Hope this helps.

Harikrishna R
  • 119
  • 1
  • 1
  • 6
  • There is no need to slice the array. Mongoose has built in methods for adding elements to a document's array. using `.push()` will work just fine. See here http://mongoosejs.com/docs/api.html#types-array-js – Matthew Antolovich Jul 28 '17 at 23:02
0
const productSchema = new mongoose.Schema(
  {
    name: {
      type: String,
    },
    description: {
      type: String,
    },
    price: {
      type: String,
    },
    categoryId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Category",
    },
    sellerId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Seller",
    },
    discount: {
      type: String,
    },
    status: {
      type: String,
      default: "active",
      enum: ["active", "inactive", "deleted"],
    },
    images: {
      type: Array,
      required: true,
    },
  },
  { timestamps: true }
);
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 16 '22 at 07:27
0

The correct way to use an array of strings in postgres is:

someFieldName: [String]

Coder Gautam YT
  • 1,044
  • 7
  • 20