Check stored value using mongoose - node.js

I’m looking for the fastest way to get all objectIDs of a collection with a privacy value 'public'.
In this image, privacy's value is 'public', so node should give me the '_id' of this object (in this example '57bc4b9f466fab7c099a3f94').
My attempt:
var mongoose = require('mongoose');
mongoose.connect('localhost:27017/databasename');
var Schema = mongoose.Schema;
var collectionsNameSchema = new Schema({
updated: {type: Date },
privacy: { type: Object }
}, {collection: 'spots'});
var collectionsNameData = mongoose.model('collectionsNameData', collectionsNameSchema);
...
collectionsNameData.find({privacy: 'public'})

From what i see you have a problem in query to mongoDB.
Try like this.
collectionsNameData.find({'privacy.value': 'public'});
This should return desired result.
You also may want to use projection as second parameter in find to return only fields that you want. Keep in mind that _id returned by default.
Hope this helps.

Related

Indexing items in array - MongoDB

I'm quite new to mongodb, hence I would like to know how the mongoose schema should look like when I need to add indexed items in an array.
Here is how I want the output to look like:
_id: some_id
users: Object
0: Array
0: some_user_id
1: some_user_id
2: some_user_id
This is the schema I tried to create, but I think I'm wrong here:
const mongoose = require('mongoose')
const timerSchema = mongoose.Schema({
users: [[]]
})
module.exports = timerSchema
Thank you in advance!
If you want timerSchema.users property to hold an array of arrays then your schema definition is correct.you can also specify type of array, refer This example to create array of arrays using mongoose Schema which contain output as well.
or if you want users as object then,
const timerSchema = mongoose.Schema({
users: {
<Field1>:[[]],
<Field2>:<Type>
}
})

Query Parse.com migrated database pointer relationship with Mongoose

Context
So we have migrated from Parse.com to an hosted MongoDB database. Now I have to write a script that queries our database directly (not using Parse).
I'm using nodejs / mongoose and am able to retrieve these documents.
Problem
Here is my schema so far:
var StorySchema = new mongoose.Schema({
_id: String,
genre: String
});
var ActivitySchema = new mongoose.Schema({
_id: String,
action: String,
_p_story: String /* Also tried: { type: mongoose.Schema.Types.ObjectId, ref: 'Story' } and { type: String, ref: 'Story' }*/,
});
I would like to write a query that fetches theses documents with the related Story (stored as a pointer).
Activity
.find({
action: 'read',
})
.exec(function(error, activities) {
activities.forEach(function(activity) {
// I would like to use activity._p_story or whatever the mean to access the story here
});
});
Question
Is there a way to have the fetched activities populated with their story, given that the _p_story field contains Story$ before the object id?
Thanks!
One option I have been looking at is the ability to create a custom data type for each pointer. The unfortunate side is Parse treats these as 'belongsTo' relationships and but does not store the 'hasMany' relationship that Mongoose wants for populate(). But once this is in place you can easily do loops to get the relational data. Not ideal but works and is what populate is really doing under the hood anyways.
PointerTypeClass.js -> This would work for populating the opposite direction.
var Pointer = function(mongoose) {
function PointerId(key, options) {
mongoose.SchemaType.call(this, key, options, 'PointerId');
}
PointerId.prototype = Object.create(mongoose.SchemaType.prototype);
PointerId.prototype.cast = function(val) {
return 'Pointer$' + val;
}
return PointerId;
}
module.exports = Pointer;
Also be sure mongoose knows about the new type by doing mongoose.Schema.Types.PointerId = require('./types/PointerTypeClass')(mongoose);
Lastly. If you are willing to write some cloudcode you could create the array of ids for your populate to know about the objects. Basically in your Object.beforeSave you would update the array of the id for the relationship. Hope this helps.

Constant property value in mongoose schema

I have schema where a property always equals 1. I have found a solution, but I don't like it:
var schema = new Schema({
a: Number
});
schema.pre('save', function(){
this.a = 1;
});
Can you please tell me if there is better way to do this? For example:
var schema = new Schema({
a: 1
});
How about using a default value, does it achieve what you want ?
var schema = new Schema({
a: {type: Number, default: 1}
});
If you want to force it, the pre version is the best option.
Another way to achieve this is to use a virtual property. Virtuals are document properties that you can get and set but that do not get persisted to MongoDB. Instead you can specify a getter function that get's called every time you access the a property:
schema.virtual('a').get(function () {
return 1;
});
Now every document of schema will have a property a that equals 1. Note however that because virtuals don't get persisted you are not able to query for them.
Store constants as model properties.
var mySchema = new Schema({
// ...
});
var myModel = mongoose.model('MyModel', mySchema);
myModel.a = 1;
Maybe too late, but for the future, you could use default value with a custom setter that always returns the old value, something like ...
var schema = new Schema({
a: {
type: Number,
default: 1,
set(value) {
return this.a;
},
}
});
The default option will initialize the field and the custom setter will ignore any new value and always reset the field to its previous value (that you set with default).

CastError: Cast to ObjectId failed for value "" at path "_id"

Well, I see that here are a few posts like this, but they didn't help me ...
let me describe my problem:
I have two Schema's
var A = new Schema({
someAttribut: {type: String},
b: {type: ObjectId, ref:'B'}
});
var B = new Schema({
someAttribut2: {type: Boolean, 'default': false'}
});
Now I'm in the situation that I already have a B-Object and I want to create an A-Object.
So i do it this way:
var a = new A(req.aFromClient); // {_id:null, someAttribute:'123', b:null}
//load b from Database ...
a.b = existingBFromDatabase; // {_id: 'Sb~Õ5ÙÐDâb', someAttribute2: false}
The b object is loaded from my monogDB. The debugger shows me a valid ObjectId (53627ed535d9d04416e26218 or Sb~Õ5ÙÐDâb) for my b .
But when I save my new A-Object, i get the error: 'CastError: Cast to ObjectId failed for value "" at path "_id"'
I don't understand why I get this error.
Firstly, I don't define the id in the schema, so mongoose should add it, which seems to work.
Secondly, I think that mongoose should generate a new ID when I create an a object.
do you have any proposal?
Based on the comment in the code, _id does have a value (of null). So you need to remove _id from req.aFromClient before creating your new A doc from it:
delete req.aFromClient._id;
var a = new A(req.aFromClient);
You should do:
a.b = existingBFromDatabase._id;
Because mongoose only works with the id of the already existing object.

Getting all documents from MongoDB instead of all Models

I'm calling MongoDB from my Node app using Mongoose like this:
var query = itemModel.find();
query.exec(function (err, items) {
console.log(err);
socket.emit("items", items);
});
I have 3 models defined like this:
var Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;
var playerModel = require('./models/player.js').make(Schema, mongoose);
var characterModel = require('./models/character.js').make(Schema, mongoose, ObjectId);
var itemModel = require('./models/item.js').make(Schema, mongoose);
my models look like this:
function make(Schema, mongoose) {
itemSchema = new Schema({
name: String
, bonus: [{
type: String
, value: Number
}]
, price: Number
, slot: String
});
return mongoose.model('Character', characterSchema);
}
exports.make = make;
For some reason I'm getting all documents, regardless of them being items, characters or players. Since I'm calling find() on itemModel I was expecting only Items, what am I doing wrong?
The model that you have shown appears to be the item model, but you are creating the model with the 'Character' name. This means that you told Mongoose about the scheme for an item and that it is stored in the 'character' collection. Assuming you've done the same for each other model (Character/Player), you've been Mongoose that everything is in the same collection.
Then you query that collection and you seem surprised that everything is stored in the same collection. It strikes me as if you have little experience with Mongoose/MongoDB, so I will suggest you download and learn to love MongoVUE. This application is a good GUI to see what is going on under the hood of the MongoDB database. While developing, you also might want to enable debugging so you can see what queries mongoose is launching to the server (mongoose.set('debug', true)).

Resources