Best way to save 2D array to MongoDb - arrays

What is the best way to save 2D array, that I have generated,problem is because it won't be small array. So is there a way to convert this 2D array to some JSON format or something and then save that with mongoose, and then to quickly convert it back, the values in are strings, all ideas all appreciated.
This is my schema:
var UserRatingSchema = new Schema({
user: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
movie: {type: mongoose.Schema.Types.ObjectId, ref: 'Movie'},
rating: String,
});
And example of array:
[nothing] Movie1 Movie2
User1 10 No rating
User2 6 5
...
Is it efficient if I save every instance to database?

you can define model like this,
location: {type: [Number]}
and define this in schema index like
UserSchema.index({location : '2d'});
now you structure will be like this
"location": [
67.0783412,
24.9044033
]
you can also modify by adding keys to the values!

Related

mongodb find where columns of arrays don't match

i am looking for a possible solution to find results from a mongodb collection where two columns of arrays don't hold the same entries.
Something like this:
Message DB structure
{
id: ObjectId,
title: String,
body: String,
recipients: [{ObjectId, ref: 'User'}],
visualized_by: [{ObjectId, ref: 'User'}]
}
when a User visualizes the message his id gets stored in the visualized_by column
Now, from an admin panel I want to visualize only the messages that were not seen by all the recipients like this:
Message.find({recipients: {$each: {$nin: "$visualized_by"}}})
OR
Message.find({$where: {recipients: {$each: {$nin: this.visualized_by}}}})
But it does not work of course.
Any help will be appreciated.
Thanks!

Mongoose indexOf in an ObjectId array

I have the following schema:
var daySchema = new Schema({
date: {
type: Date,
required: true
},
activities: [{
type: Schema.Types.ObjectId,
ref: 'Activity'
}]
});
And I am removing an activity within the daySchema:
var index = day.activities.indexOf("584aa9c16791eb1ec4ad8e73");
day.activities.splice(index, 1);
Can someone explain me why this works ?. The array "activities" is an array of "ObjectId". So the "indexOf" should not work with objects, but still the "indexOf" is able to find the element based on the id. This is driving me crazy, is something else going on here, maybe a map function inside ObjectId ?
This works because Mongoose wraps an array in MongooseArray which provides its own indexOf method which supports this string-based comparison rather than the strict equality test used by the native array implementation.

MongoDB : return a list of all subdocument

I'm trying to learn Meteor/Mongo, but each time you think to make progress, a "simple thing" seems totally beyond reach...
I have a very simple document :
_id : abcd
field : xyz
subdoc [
{_id: 123, email: abc, name: abc}
{_id: 234, email: abc, name: xyz}
{_id: 853, email: abc, name: pmu}
]
And I want to return a list of all my subdocuments.
Put in another word, I'd like to get a list like this one, in my HTML template using "each":
_id: 123 email: abc name: abc
_id: 234 email: abc name: xyz
_id: 853 email: abc name: pmu
But I'm totally unable to achieve any results with .dot notation..
Any clue?
Thanks a lot..
myCollection.find({_id: 'abcd'}).fetch().forEach(function(item) { return item.subdoc; });
or even simpler with findOne
myCollection.findOne({_id: 'abcd'}).subdoc;
Note:
In the 2 cases only one document is returned by the _id (since _id is unique) you will get the subdoc array.
If you use the first solution and your query returns multiple documents, then you will get an array of Arrays.
If what you want is a flat array from the array of Arrays, you need to flatten that array
with underscore that would be
flattened = _.flatten(nestedArray)
If you are using newer version of MongoDB (4.x), you can use aggregate functionality. So, instead of flattening in JavaScript, you can do this on Database Server itself.
myCollection.aggregate([
{$unwind : "$subdoc"},
{$project : {
_id : 0,
id : "$subdoc._id",
name : "$subdoc.name",
email: "$subdoc.email"
}
}
])

Strategy for sharing and reusing of schema parts in mongoose.js

Suppose, I have two schemas, e.g. for person and company. Both of them should have an address, which consists of a street name, number, zip and city.
What would be the strategy to avoid copying the address properties between the two schema definitions? I read about sub docs, but they seem to be (1) tied to exactly one parent schema, (2) always occur in an array.
Almost too obvious, but this is what I came up with finally:
Define the reusable portions separately, however, contrary to my first thoughts: do not use a Schema here:
var addressSubschema = {
street: String, number: String, zip: String, city: String
}
Simply include this part in actual schemas:
var personSchema = new mongoose.Schema({
name: { type: String, required: true },
title: { type: String },
address: addressSubschema
});
var companySchema = new mongoose.Schema({
name: { type: String, required: true },
addresses: [addressSubschema]
});
My (naive?) approach might be to create a new schema for address, and use Mongoose's population mechanic to link to a given address by ObjectID. However, this is essentially emulating a relational DB behaviour, and I'm not sure how PC that is when using a flat-file store like Mongo.

Mongoose schema to require array that can be empty

I have this schema
var StuffSchema = new mongoose.Schema({
_id: { type: String, required: true, unique: true },
name: { type: String, required: true }
});
mongoose.model('Stuff', StuffSchema);
Works fine.
Now I need to add another schema "Cargo" containing this
mystuff: { type:[String], ref: 'Stuff', required:true},
that is, I want mystuff to contain array of ids of Stuff, but this fails with validation error when running this code
mongoose.model('Cargo').create( some data...)
if I use an empty array for the mystuff field.
It seems to work if I change the Cargo schema to
mystuff: { type:[String], ref: 'Stuff'},
but I want the mystuff field to be required and allow empty arrays
What can I do to make this happen?
Empty arrays are created by default (see also this). The attribute required: true requires the array to have at least one element in it (source code). You can remove that attribute to get your desired behavior.
(Aside, mongoose assigns a default _id field with the type ObjectId to all schemas. Declaring it is unnecessary, and using a string is not typical, although certainly allowed.)
Edit Nov 2017: This is a candidate change in Mongoose 5. See https://github.com/Automattic/mongoose/issues/5139.

Resources