Unique documents using multiple values in Mongoose Schema - node.js

I have a special case where our collection needs to make sure each document is unique based on a combination of the email address, and the sweepstakes_id. I've looked all over, but I can't find how to accomplish this type of validation.
Schema definition:
var submissionSchema = new Schema({
client_id: {
type: Schema.Types.ObjectId,
ref: 'Client',
index: true
},
sweepstakes_id: {
type: Schema.Types.ObjectId,
ref: 'Sweepstakes',
index: true
},
email: {
type: String,
index: true
},
data: {
type: Schema.Types.Mixed,
default: []
}
});

You can enforce that using a unique index that includes both fields:
submissionSchema.index({ email: 1, sweepstakes_id: 1 }, { unique: true });

Related

How to create a new objectID in mongoose schema?

I want to generate two different objectIds in mongoose schema. One for departureLocation and one for arrivalLocation and want to reference it later.
I imported the object id from mongoose like this
let id = new mongoose.Types.ObjectId()
now I want to generate two different object ids like I said above
const routeSchema = new mongoose.Schema(
{
location: {
departureLocation: {
name: {
ref: "Location",
type: String,
required: true,
},
//want to create new object id here,
subLocation: [String],
_id: {
type: String,
},
},
arrivalLocation: {
name: {
ref: "Location",
type: String,
required: true,
},
//want to create new object id here,
subLocation: [String],
_id: {
type: String,
},
},
},
duration: {
type: Number,
required: true,
},
busId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Bus",
required: true,
},
date: {
type: String,
required: true,
},
},
{
timestamps: true,
}
);
MongoDB will automatically create _id for an object in a schema. You do not need to create one. In this schema, there will be 4 automatically generated _ids one for location, one for departureLocation, one for arrivalLocation, and one for the overall schema.

Mongoose – querying subdocuments referenced by ID

I have 2 schemas connected like this:
const Brand = new mongoose.Schema({
_id: { type: String, required: true },
name: {
type: String,
required: true,
},
products: [{
type: String,
ref: 'Product',
}],
});
const Product = new mongoose.Schema({
_id: { type: String, required: true },
name: {
type: String,
required: true,
},
type: {
type: String,
required: true,
},
});
I want to find brands that have certain types of products, so I wrote a query (not including async/await and promises in the code below for simplicity)
const docs = Brand.find({ 'products.type': 'my-type-here' })
.populate([
{
path: 'products',
},
])
.sort({ index: 1 })
.exec();
This gives me 0 results, yet I know that there are brand with the type of products. What am I doing wrong here? Is it connected with the fact, that products are only referenced by their ids when I invoke find method?

Find all the documents that has same subdocuments mongoose

I have postSchema which references the tagsSchema.
var tagsSchem = new Schema({
name: {
type: String,
required: true
}
}, {
timestamps: true
});
// create a schema
var postsSchema = new Schema({
title: {
type: String,
required: true,
unique: true
},
mainImage: {
type: String
},
category: {
type: String,
required: true
},
body: {
type: String,
required: true
},
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
tags: [tagsSchem]
}, {
timestamps: true
});
One post can contain any no. of tags. So if a post has 3 tags then I want to get all the posts with those 3 tags without querying it multiple times. Is it possible?
When you perform find, you can use the $in option to find values that are in your array. For example:
posts.find({tags:{$in:{["tag1","tag2","tag3"]}}, function(err,data) {
... //Your code here
}
This will take all the posts that contains one of the three tags. It's important you have to pass an array in the $in option. This should work.

Remove multiple records from a collection- MongoDB

I have two models with the following schemas:
Map:
var MapSchema = mongoose.Schema({
ownerId:{
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
mapName: {
type: String
},
mapImagePath:{
type: String,
required: true
},
createdAt: { type: Date, default: Date.now },
devices: [{type: Schema.Types.ObjectId, ref: 'Device'}]
});
Device:
var DeviceSchema = mongoose.Schema({
deviceName:{
type: String,
required: true,
index: true,
unique: true
},
roomCapacity: {
type: Number
},
roomImagePath:{
type: String,
},
mapId:{
type: Schema.Types.ObjectId,
ref: 'Map',
required: true
},
coords:{
type: [Number], //[xcoord, ycoord]
required: true
},
status:{
type: String,
required: true,
default: 'Available'
},
user:{
type: String,
},
createdAt: { type: Date, default: Date.now }
});
As you can see, one map has many devices. Now, When I delete a map, I want to delete all of the devices that belong to it. This should be easy because each map has an array of it's device ID's. But I can not seem to find a way to delete multiple records from a collection at once. I delete my map with this function:
module.exports.deleteMap = function(mapId, callback){
Map.findOneAndRemove({_id: mapId}, callback)
};
This returns the map so I can access it's device ID's as map.devices. However, how can I now use map.devices to remove all of these from the device collection? I was thinking something like device.remove(map.devices) ?
You can first find the map object and use the array of device _ids with the $in operator to remove all the devices in the map. Below is some (untested) sample code.
module.exports.deleteMap = function(mapId, callback) {
Map.findOneAndRemove({_id: mapId}, function(dbErr, map) {
if(dbErr) {
return callback(dbErr);
}
Device.remove({_id: {$in: map.devices}}, function(dbErr) {
if(dbErr) {
return callback(dbErr);
}
return callback(undefined, map);
});
});
};

Mongoose Populate - array

can someone please help me with population of this schema? I need to populate array of Staff by their userId.
var PlaceSchema = new Schema ({
name: { type: String, required: true, trim: true },
permalink: { type: String },
country: { type: String, required: true },
...long story :D...
staff: [staffSchema],
admins: [adminSchema],
masterPlace:{ type: Boolean },
images: []
});
var staffSchema = new Schema ({
userId: { type: Schema.Types.ObjectId, ref: 'Account' },
role: { type: Number }
});
var adminSchema = new Schema ({
userId: { type: Schema.Types.ObjectId, ref: 'Account'}
})
var Places = mongoose.model('Places', PlaceSchema);
I tried to use this query, but without success.
Places.findOne({'_id' : placeId}).populate('staff.userId').exec(function(err, doc){
console.log(doc);
});
Polpulation is intended as a method for "pulling in" information from the related models in the collection. So rather than specifying a related field "directly", instead reference the related fields so the document appears to have all of those sub-documents embedded in the response:
Places.findOne({'_id' : placeId}).populate('staff','_id')
.exec(function(err, doc){
console.log(doc);
});
The second argument just returns the field that you want. So it "filters" the response.
There is more information on populate in the documentation.

Resources