MongoDB Insert Issue - mongodb

This is from MongoDB.
I am following this tutorial.
I have the collection as shown below:
$ show collections
mycol
mycollection
system.indexes
test
tutorialspoint
Then when I attempt to insert a record in to the collection, using the syntax below, I get the error:
2014-04-18T08:03:55.168-0400 SyntaxError: Unexpected token ILLEGAL
db.mycol.insert({
_id: ObjectId(7df78ad8902c),
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by: 'tutorials point',
url: 'http://www.tutorialspoint.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
Below is the copy/paste from mongodb
db.mycol.insert({
... _id: ObjectId(7df78ad8902c),
... title: 'MongoDB Overview',
... description: 'MongoDB is no sql database',
... by: 'tutorials point',
... url: 'http://www.tutorialspoint.com',
... tags: ['mongodb', 'database', 'NoSQL'],
... likes: 100
... })
2014-04-18T08:03:55.168-0400 SyntaxError: Unexpected token ILLEGAL

Try the insert without the _id field. This is automatically generated by Mongodb.
Like this:
db.mycol.insert({
title: 'MongoDBOverview',
description: 'MongoDBisnosqldatabase',
by: 'tutorialspoint',
url: 'http: //www.tutorialspoint.com',
tags: [
'mongodb',
'database',
'NoSQL'
],
likes: 100
});
If you want to use the _id field:
Mongodb docs: Insert a document using the _id field
Ex: _id: 10
The value of _id must be unique within the collection to avoid
duplicate key error.

The value needs to be in quotes. Also, the string in the example is the wrong length. Insert something without specifying the _id field, then do a db.mycol.find() to see the correct format. The field is 12 bytes according to the documentation. The 24-character string is using 2 hex characters per byte. (NOTE: I am also a mongoDB noob, so I am sure there may be flaws with this answer.)

Related

How to make Mongoose model.insertMany insert documents with numerical and ordered ids?

I have this route in the backend express server:
router.route('/fillInformationAssetsSeverityEvaluation').post((req, res) => {
informationAssetsSeverityEvaluationRow.remove({}, (err) => {
if (err)
console.log(err);
else
// res.json("informationAssets Collection has been dropped!");
res.json('information Assets Severity Evaluation data has been received on the server side')
informationAssetsSeverityEvaluationRow.insertMany([req.body[0]], {
multi: true
}).then(documentsInserted => {
console.log('[req.body[0]]: ', [req.body[0]]);
console.log('documentsInserted: ', documentsInserted);
console.log('You have succesfully inserted ', documentsInserted.length, ' documents in informationAssetsSeverityEvaluation collection');
});
});
})
For the sake of simplicity, I am inserting only one document.
[req.body[0]]
{ REF: 'REFSHIT',
confFin: 'A',
confRep: 'A'}
But, in the real applications, I am inserting multiple documents similar to that.
This consoleLog :
console.log('documentsInserted: ', documentsInserted);
logs:
documentsInserted: [ { _id: 5d3453afc302d718e4870b53,
REF: 'REFSHIT',
confFin: 'A',
confRep: 'A'}]
As you see the id is automatically generated:
> _id: 5d3453afc302d718e4870b53
What I would like is: The ids of the different documents to be "numerically ordered". I.e:
Document 0 would have id 0
Document 1 would have id 1
Document 2 would have id 2
And so on and so forth.
After having made some research, I found out that I can do this manually by inserting the id manually inside the updateMany objects.
However, since I receive the documents objects from the request body, this is not a viable solution.
Any help?
Finally after trying four modules and a couple of days of trying for something that should be native to mongodb, I have found a simple solution. I hope it helps someone.
1/ Install mongoose-plugin-autoinc
2/
import mongoose from 'mongoose';
import { autoIncrement } from 'mongoose-plugin-autoinc';
const connection = mongoose.createConnection("mongodb://localhost/myDatabase");
const BookSchema = new mongoose.Schema({
author: { type: Schema.Types.ObjectId, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});
BookSchema.plugin(autoIncrement, 'Book');
const Book = connection.model('Book', BookSchema);
2/ In my case I have the models defined in models.js and the connection defined in server.js so I had to write this :
BookSchema.plugin(autoIncrement, 'Book');
in models.js
and instead of
const Book = connection.model('Book', BookSchema);
I have:
module.exports = {
informationAssetsRow: mongoose.model('informationAssetsRow', informationAssetsRow),
};
And in server.js:
const {
informationAssetsRow,
} = require('./models/models')

Elasticseach | Unable to add analyzers to date type

I am migrating from Elasticsearch v2.1 to v6.1.1 and in v2.1 my mappings for dob which worked fine now throws an error.
dob: {
type: 'date',
format: 'strict_date_optional_time||epoch_millis',
term_vector: 'yes',
analyzer: 'ngram_analyzer',
search_analyzer: 'standard',
copy_to: '_all'
}
I now get the following error:
"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"Mapping definition for [dob] has unsupported parameters: [search_analyzer : standard] [analyzer : ngram_analyzer] [term_vector : yes]"}],"type":"mapper_parsing_exception"
There seems to be an overall problem with date types getting analyzers now. Why is this and how can I solve this problem? Thanks!
As far as I know, these settings have never been supported for date fields. What I suggest you do is to create a text sub-field in your dob field so that you can continue to use your analyzers.
dob: {
type: 'date',
format: 'strict_date_optional_time||epoch_millis',
fields: {
text: {
type: 'text',
term_vector: 'yes',
analyzer: 'ngram_analyzer',
search_analyzer: 'standard',
copy_to: '_all'
}
}
}

Correct way to do a PATCH upsert request

What is the proper way to request the following upsert to a REST API?
I'm struggling to structure a NoSQL collection, which is based on the most requested returns to the front-end application.
Suppose you have the following document:
{
'user' : {
'private_comments': [
//object available only to user 1
{
'id': 1,
'bar': 'He is very good',
'...': '...'
},
//object available only to user 2
{
'id': 2,
'bar': 'He is very bad',
'...': '...'
}
],
'public_comments': '' //infos available to all users
}
}
It is needed to upsert an element to the user.private_comments array.
According to https://www.rfc-editor.org/rfc/rfc6902#appendix-A.5, I could request a replace instruction PATCHing the following data:
{ 'op': 'replace', 'path': '/user/comments/$index', 'value': 'Actually, he is OK'}
The problem is that '$index' is unknown in this case.
A possible solution that I came up with was to create something like the following operation:
{ 'op': 'upsert', 'find_by': 'id', 'find': 1, 'path': '/user/comments', 'value': 'Nope, he really sucks' }
However, the user implementing the API should't provide the id value inside the PATCH request, because this value is already accessible via the receive token. Should I simplify the operation to:
{ 'op': 'upsert', 'path': '/user/comments', 'value': 'Nope, he really sucks' }
and treat it at the backend, so when it's and upsert operation without 'find' and 'find_by' variables I assume 'find_by': 'id' and 'find': value_from_token?
Also, I cannot do a simple GET/UPDATE at the hole document because the user doesn't receive the hole document, so an update would compromise the data.

MongoDB - "The dollar ($) prefixed field \'$$hashKey\' in \'fieldName".$$hashKey\' is not valid for storage.'"

While trying to update a document I'm getting the above error for the field timesToDisplay.
MongoDB version 2.6.7.
The whole model:
msg = {
'name': '',
'template': '',
'displayDurInMilliSec': 0,
'timesToDisplay': [],
'images': [],
'texts': [],
'screen': []
}
I guess I will be getting the same error with the other 3 array fields.
I've tried using $set but sill getting the same error.
The code:
function updateMessage(msg) {
var conditions = {_id: msg._id}
, update = { 'name': msg.name,
'template': msg.template,
'displayDurInMilliSec': msg.displayDurInMilliSec,
'timesToDisplay': msg.timesToDisplay,
'images': msg.images,
'texts': msg.texts,
'screen': msg.screen
}
messageModel.update(conditions, update, callback);
function callback(err, numAffected) {
if (!err) console.log(numAffected)
else console.log(err)
}
}
EDIT: The msg parameter is a document in itself:
{ _id: '557d58abd54955480db6694f',
name: 'msg99',
timesToDisplay: [ { startDate: '2015-06-19T21:00:00.000Z',
'$$hashKey': 'object:214',
endDate: '2015-06-25T21:00:00.000Z',
daysOfTheWeek: [Object],
startTimeOfDay: '11',
endTimeOfDay: '13' } ],
images: [],
texts: [],
screen: [ 1 ],
'$$hashKey': 'object:54',
displayDurInMilliSec: '40189',
template: 'templates/Template2.html' }
The $$hashkey field is added by AngularJS when working with ngRepeat or ngOptions. In the case of ngRepeat you can change the repeat string by appending track by $index to it. For using ngOptions you'll have to filter out that field yourself. AngularJS provides a quick solution for filtering it out: angular.toJson. This will filter out all fields prefixed with two dollar signs. Check out the documentation.
I realize that this isn't a MongoDB answer, but this specific error ($$hashkey), is usually due to AngularJS.

MongoDB, add new { field : value } in existing embedded document with multiple level dot notation?

What I am trying to do is add a new {field:value} for a blog post. So for example, if I wanted to start tracking impressions on websites.blog_posts.url: 'http://www.example.com/01.html' how can I add that impressions attribute for that blog post?
My current document structure:
{
email_address: 'webmaster#example.com',
password: 'random_password',
first_name: 'John',
last_name: 'Doe',
user_type: 'WEBMASTER',
newsletter: 'NO',
websites: [{
main_title: 'My Blog Website',
main_url: 'http://www.example.com',
blog_posts: [{
url: 'http://www.example.com/01.html',
title:'My first blog post',
description: 'My first description.'
}, {
url: 'http://www.example.com/02.html',
title: 'My second blog post',
description: 'My second description.'
}, {
url: 'http://www.example.com/03.html',
title: 'My third blog post',
description: 'My third description.'
}, {
url: 'http://www.example.com/04.html',
title: 'My fourth blog post',
description: 'My fourth description.'
}]
}]
}
Here is what I thought would work using update and making upsert TRUE.
db.my_collection.update( {'websites.blog_posts.url': 'http://www.example.com/01.html' }, {'$set': {'websites.blog_posts.impressions': 549}}, true )
The error that I received is:
*can't append to array using string field name [blog_posts]*
Maybe "$set" is not correct for this or maybe I can not reference that deep with dot notation? I just started using MongoDB yesterday, any help would be great.
Thank you!
What you're trying to do is not possible given your schema. Dot-notation can be multi level but if there's more than one level that is an array it can no longer be addressed using the positional operator '$'.
E.g. you'd need to do :
db.my_collection.update(
{'websites.blog_posts.url': 'http://www.example.com/01.html' },
{'$set': {'websites.$.blog_posts.$.impressions': 549}},
true );
But having two position operators in the update is not possible since MongoDB can only determine the position of an element in the first array.
Your only option is to redesign your schema to have a dedicated collection of user websites (which is better for other reasons too in this case).