Mongoose compound indexes not being created (Too long) - node.js

I'm having some issues creating multiple compound indexes on one of my schemas in MongoDB. When using MongoLab, I know some indexes are not created when they are too long, due to a naming issue. So I suspect this might be the reason why some are not created
var Schema = new mongoose.Schema({ ... });
// Created
Schema.index({
one: 1,
three: 1
});
// Not Created
Schema.index({
one: 1,
two: 1,
three: 1,
four: 1,
five: 1,
six: 1,
seven: 1,
eight: 1,
nine: 1,
ten: 1
});

There is a limitation to the default index name (https://docs.mongodb.org/manual/reference/limits/#Index-Name-Length)
You can specify custom index name by passing addition option object to Schema.index
Schema.index({
one: 1,
two: 1,
three: 1,
four: 1,
five: 1,
six: 1,
seven: 1,
eight: 1,
nine: 1,
ten: 1 },
{ name: 'my_index_name' }
);

Related

MongoDB query fast in mongo shell but slow/times out in nodejs

The following query takes approximately 54ms in the mongo shell, but times out after a minute in the nodejs driver:
db.posts.find(
{
parentId: 10,
modifiedGmt: {
"$gte": new Date("2017-01-01T00:00:00.000z")
},
postType: {
"$in": ["type1", "type2"]
}
},
{
_id: 1,
parentId: 1,
postId: 1,
url: 1,
modifiedGmt: 1,
authors: 1,
taxonomy: 1,
postType: 1
}
).sort({modifiedGmt: 1}).limit(2400)
Explain shows that the query is using existing indexes. If I drop the limit to something very low like 10, it won't time out but it will take far, far too long. I'm not really sure where to go with this. It's a large collection but with the indexes in place and the limit sub-10000 I don't see why it would be so slow.
Any ideas?
I'm suspecting that the .sort is not able to use your index.
I would recommend to have a read on this page sort-operator-and-performance.

Mongoose push item to array if not exists

I have a model schema like this:
Collection: {
irrelevant fields,
object: {
more irrelevant fields,
array:
[
{
field1,
field2,
_id: false
}
]
}
}
I want to push to array any object {field1, field2} that does not repeat with field1 already existing in array (in an updateOne query).
field2 is constantly updating itself and i have tried addtoset but it considers field2 so it ends up adding another item i don't want to add.
For example:
array:[
{field1: 1, field2: 6},
{field1: 2, field2: 4},
{field1: 3, field2: 1}
]
if i would want to push {field1: 2, field2: 6} it should not let me push it because the field1:2 already exists in array.
(using addtoset, even it does check that the field1:2 already existis, it ends up adding te object because of field2 being different)
array:[
{field1: 1, field2: 6},
{field1: 2, field2: 4},
{field1: 3, field2: 1}
{field1: 2, field2: 6}
]
You could use the pipeline form of update with the $cond operator. If the field1 value already exists, keep the value of the array the same, if not, append the new value to the end.
Perhaps something similar to:
const newValue = {field1: 2, field2: 6};
db.collection.update({match criteria},
[{$set:{
array:{
$cond:{
if: {$in: [newValue.field1, "$array.field1"]},
then: "$array",
else: {$concatArrays: ["$array", [newValue]]}]}
}
}
}}]
)

Is mongodb update with query atomic?

mongodb write and update opertaions are atomic, as stated in their docs.
But does it also atomic when using query?
For example:
db.collection.update( { id : 1 , count : 0 } , { $inc : { count : 1 } } )
If I execute this operation in a multi threaded environment, is it possible that at some point the value of count in the document with id equal to 1 will be greater than 1?
Any modification to a single document is atomic.
Using your example, let's say there are two threads trying to update that document using the same query:
Thread A: db.collection.update({_id: 1, count: 0}, {$inc: {count: 1}})
Thread B: db.collection.update({_id: 1, count: 0}, {$inc: {count: 1}})
with the collection containing the document:
collection: {_id: 1, count: 0}
If thread A managed to update the document before thread B, the collection would then contain:
collection: {_id: 1, count: 1}
Thread B will search for a document matching _id:1, count:0 but since that document was already modified by thread A, the update in thread B will not proceed (since the document no longer "exists" as thread B is concerned).
In other words, thread A will return nMatched: 1, nModified: 1, and thread B will return nMatched: 0, nModified: 0.
To specifically answer your question, there will not be a case where a document {_id: 1, count: 2} will exist.

Referencing an object array for cascading select options with angular-formly

I'm creating a form which will have field options dependent upon choices earlier in the form, referencing a JSON array. I've studied the Cascade Select example, but haven't quite wrapped my head around how the controllers work in it. Would someone mind helping me adapt the concepts of the Cascade Select example to reference a JSON array?
Here is a link to a JS Bin illustrating what I'm trying to accomplish (be sure to "Run with JS"). I would like fields whose options are populated with respect to an array and are filtered based on previous selection. I've figured out how to do the first level of options for selecting a sport with a simple for-loop function passed to the "options" argument in the form element; but I need a hand moving to the next stage. Ideally, I would like to have more depth; i.e. Pick a Sport > Pick a Team > Pick a Player; but I should be able to figure it out with just the first filtered select options.
Thank you!
Actually this is totally unrelated to angular-formly. Your data model is not properly modeled, you should use the concept of foreign keys. A more appropriate modeling would be:
var sports = [{
id: 1,
name: 'Soccer'
}, {
id: 2,
name: 'Basketball'
}];
var teams = [{
id: 1,
fk: 1,
name: 'Bayern Munich'
}, {
id: 2,
fk: 1,
name: 'Real Madrid'
}, {
id: 3,
fk: 2,
name: 'Cleveland'
}];
var player = [{
id: 1,
fk: 1,
name: 'Mario Götze'
}, {
id: 1,
fk: 2,
name: 'Javier Hernandez'
}, {
id: 2,
fk: 3,
name: 'LeBron James'
}];
A working example is shown here: http://output.jsbin.com/jinaca

Nested arrays in Mongoose

In the collection I'm working on, a document looks like this:
{
name: 'Myname',
other: 'other',
stuff: [
['something', 12, 4, 'somethingelse'],
['morestuff', 2, 4, 8],
['finally', 12, 'again', 58],
]
}
I wrote this Mongoose schema to access it:
var MyDocSchema = new Schema({
name: String,
other: String,
stuff: [],
});
When I query a doc, everything works well, the output shown in the console is right. But when, I try to do console.log(myDoc.stuff), I got the following:
['something', 12, 4, 'somethingelse', 'morestuff', 2, 4, 8, 'finally', 12, 'again', 58]
instead of
[
['something', 12, 4, 'somethingelse'],
['morestuff', 2, 4, 8],
['finally', 12, 'again', 58],
]
What am I doing wrong? Thank you for your help!!
Disclaimer: This response is pretty dated, 2012! It might not be the most accurate.
From the Mongoose documentation.
http://mongoosejs.com/docs/schematypes.html: Scroll down to the Array section:
Note: specifying an empty array is equivalent to [Mixed]. The
following all create arrays of Mixed.
Details on what that means is in the Mixed section right above the Array section.
Here's what you need to do.
Define a schema for the embedded documents:
var Stuff = new Schema({
name: String,
value1: Number,
...
});
Use that instead of an empty array []:
var MyDocSchema = new Schema({
name: String,
other: String,
stuff: [Stuff],
});

Resources