is there ways to enter special characters in mongodb in a collection - database

i am going to add special caracter in fiels like
db.student.insert({"name":"abc","f/name":"abc"})
NOTE : Here mongodb show an error f/name is not adding so how i can add that ?
answer in more ways,

While insert is deprecated (should use insertOne()), it still seems to work fine...
Enterprise replSet [primary] barrydb> db.student.insert({"name":"abc","f/name":"abc"})
DeprecationWarning: Collection.insert() is deprecated. Use insertOne, insertMany, or bulkWrite.
{
acknowledged: true,
insertedIds: { '0': ObjectId("63d1c044eb9ba7eec74dda8b") }
}
Enterprise replSet [primary] barrydb> db.student.find()
[
{
_id: ObjectId("63d1c044eb9ba7eec74dda8b"),
name: 'abc',
'f/name': 'abc'
}
]

Related

Mongodb query to find element value type of nested array or object in a field

I have mongodb data model where I have some array fields that contain embedded objects or arrays. I have some inconsistencies in the field in question because I've tweaked my application logic. Initially, my model looked like this:
Initial Setup of Results collection
"competition" : "competition1",
"stats" : [
{
"stat1" : [],
"stat2" : []
}
]
However, I saw that this wasn't the best setup for my needs. So I changed it to the following:
New Setup of Results collection
"competition" : "competition1",
"stats" : [
{
"stat1" : 3,
"stat2" : 2
}
]
My problem now is that documents that have the initial setup cause an error. So what I want is to find all documents that have the initial setup and convert them to have the new setup.
How can I accomplish this in mongodb?
Here is what I've tried, but I'm stuck...
db.getCollection('results').find({"stats.0": { "$exists": true }})
But what I want is to be able to do something like
db.getCollection('results').find({"stats.0".stat1: { "$type": Array}})
Basically I want to get documents where the value of stats[0].stat1 is of type array and override the entire stats field to be an empty array.
This would fix the errors I'm getting.
$type operator for arrays in older versions works little differently than what you might think than $type in 3.6.
This will work in 3.6
db.getCollection('results').find( { "stats.0.stat1" : { $type: "array" } } )
You can do it couple of ways for lower versions and It depends what you are looking for.
For empty arrays you can just check
{"stats.0.stat1":{$size:0}}
For non empty arrays
{"stats.0.stat1": {$elemMatch:{ "$exists": true }}}
Combine both using $or for finding both empty and non empty array.
For your use case you can use below update
db.getCollection('results').update({"stats.0.stat1":{$size:0}}, {$set:{"stats":[]}})

Mongodb 3.6.0-rc3 array filters not working?

I'm trying to use array filters in mongodb 3.6.0-rc3, exactly like in doc example but not getting any rows affected and no error.
Example is simplified. I know this can be done with $ as positional operator but I'm planing to use this feature for two level nested arrays.
db.getCollection('books').update({},
{
$set: { "authors.$[element].firstName": "Joe" }
},
{
arrayFilters: [ { element: { "_id": ObjectId("some_id") } } ],
multi: true
})
Anyone tried this yet?
Are you typing this in robomongo? It looks like it! If so it won't work. Read my note on Updating a Nested Array with MongoDB where I say this does not work in an "older shell" or anything based on it ( which robomongo is a shell based build ) because of the way the shell helper methods are currently implemented:
NOTE Somewhat ironically, since this is specified in the "options" argument for .update() and like methods, the syntax is generally compatible with all recent release driver versions.
However this is not true of the mongo shell, since the way the method is implemented there ( "ironically for backward compatibility" ) the arrayFilters argument is not recognized and removed by an internal method that parses the options in order to deliver "backward compatibility" with prior MongoDB server versions and a "legacy" .update() API call syntax.
So if you want to use the command in the mongo shell or other "shell based" products ( notably Robo 3T ) you need a latest version from either the development branch or production release as of 3.6 or greater.
So if you want to "play with" the release candidate, either use the bundled mongo shell with that version or simply run your code through any standard driver.
db.getCollection('books').update({},
{
$set: { "authors.$[element].firstName": "Joe" }
},
{
arrayFilters: [ { "element._id": ObjectId("some_id") } ],
multi: true
})
this BUG,just upgrade studio-3t version to 2018.6.1,use $ and arrayFilter OK.I try it in mongo4.0.4 and studio-3t

How to publish a mongodb array length as an additional collection field?

I have a mongodb collection with the following fields:
_id
name (string)
[items] (array of string)
secret (boolean)
I want to publish the all the _id, name fields and the item array length only (excluding the secret field) where the secret field is true.
I have read somewhere that I can add additional document properties in my find query, but my google foo does not work.
Here is what my publish method looks like without the additional items_count property:
Meteor.publish("all_items", function() {
return myItems.find(
{secret: true},
{fields:
{_id:1,name:1}
});
});
How can I create an additional field from the [item] length in my publication?
EDIT: it seems that I need to use an aggregate function and the $projectoperator. And it is not supported by meteor.
Can anyone confirm this to me (i.e. it is the only option and it is not supported)?
You can add aggregation framework support to Meteor, and then use a simple aggregation pipeline with $project stage as you mentioned, like to following:
myItems.aggregate(
[
{$match: {secret: true}},
{$project: {_id: 1, name: 1, items_count: {$size: '$items'}}}
]
)

node.js: JSON dot notation + access array key

I have a site setup using node.js, express, mongoDB & mongoose. Mongoose is giving me an array that contains this:
[ { title: 'HTML in depth',
author: 'kevin vanhove',
_id: 53039f264a6324978c70084b,
chapters:
[ { _id: 53039f264a6324978c70084d,
content: '/jow',
title: 'History of HTML' },
{ _id: 53039f264a6324978c70084c,
content: '/w3c',
title: 'What is the W3C' } ],
__v: 0 } ]
I'm getting this result in my terminal using this code:
function indexData(books){
console.log(books)
res.render("index.html", {context:books, partials:{footer:"footer", header:"header"}})
}
Now i'm trying to access the value in chapters[0].title, but i'm getting an error:
console.log(books[0].chapters[0].title)
TypeError: Cannot read property '0' of undefined
I'm confused here, am i accessing the value using the right dot notation?
UPDATE 1: complete terminal output
24 Feb 10:56:47 - [nodemon] restarting due to changes...
24 Feb 10:56:47 - [nodemon] starting `node app.js`
Mongoose: books.find({}) { fields: undefined }
/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/routes/routes.js:45
console.log(books[0].chapters[0].title)
^
TypeError: Cannot read property '0' of undefined
at indexData (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/routes/routes.js:45:32)
at Promise.<anonymous> (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/routes/routes.js:37:31)
at Promise.<anonymous> (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)
at Promise.EventEmitter.emit (events.js:95:17)
at Promise.emit (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38)
at Promise.fulfill (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/node_modules/mpromise/lib/promise.js:97:20)
at /Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/lib/query.js:1052:26
at model.Document.init (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/lib/document.js:250:11)
at completeMany (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/lib/query.js:1050:12)
at Object.cb (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/lib/query.js:1017:11)
24 Feb 10:56:49 - [nodemon] app crashed - waiting for file changes before starting...
Partial solution:
I was trying to get to the chapters data. Updating my mongoose schema to include the chapters data did the trick.
var booksSchema = new mongoose.Schema({
title: String,
author: String,
chapters: [
{
title: String,
content: String
}
]
});
This doesn't work an that way on the Mongoose (server) side. The result from find() is a cursor that you need to either iterate or convert via toArray from the native driver part. Something like this
(Assuming Schema Books):
Books.collection.find({}).toArray(function(err, results) {
// results is an array that you can do something with here.
});
Of course if you have defined additional Schema for arrays and their documents that are not embedded, then this is going to hurt a bit more and you need to use the iterative methods to get your results as an array.
If you want specific items from your books and sub-items within, then you would be better of tuning your find query using the operators rather than returning all results. Or even the aggregation pipeline may be of some help.

What's the correct way to use deliveryTime?

self.mirror_service.timeline().insert(
body={
'text': '123 456',
'notification': {
'deliveryTime': rfc3339.timestamp_from_tf(timestamp_after_duration),
'level': 'DEFAULT'
},
}
).execute()
The formatted timestamp looks like this: 2013-06-16T02:47:33-00:00 which seems to be correct but I'm getting a bad request/400. Is there an example of using this property?
2013-06-16T15:46:51.561Z
Is an example of a timestamp string that the mirror API likes.
If I just remove the trailing Z I start getting a 400. I also see you have a hyphen in your timestamp string that should probably be removed.
Note that even if you get a 200, you might not get the behavior you expect. There is an open issue in the tracker about deliveryTime.
Here is my entire notification JSON that works:
"notification": {
"level": "DEFAULT",
"deliveryTime": "2013-06-16T15:46:51.561Z"
}

Resources