MongoDB: FailedToParse: Bad characters in value - mongodb

mongodump command:
mongodump --host myhost.com --port 12345 --username myUsername --password PSWRD --out /opt/somepath --db myDb --collection my_collection --query "{ content_type_id: { \$not: { \$eq: db.my_type.findOne({slug: 'form_submissions'} )._id } } }" --verbose
Results in:
assertion: 16619 code FailedToParse: FailedToParse: Bad characters in value:
offset:33 of:{ content_type_id: { $not: { $eq: db.my_type.findOne({slug: 'form_submissions'} )._id } } }

That's not a valid query. --query must be a JSON document. Your error is in thinking that mongodump is something programmatic like the mongo shell that can evaluate the findOne and substitute the value into the query. This is not the case. You can find the _id from the result of the findOne and put it in the mongodump --query manually. Use extended JSON format for an ObjectId type, if that is the type of _id.

Related

Running batch operations in MongoDB/ Robo3t

I have a list of users in a file and I want to update their record in a collection.
i.e
db.getCollection('users').update({username: "<a user>"}, { $set: { <set some values here> }})
How can I feed a list of users into this command or something similar in Robo 3T or from a terminal command line?
The following from the command line seems the easier options:
Option A) generate the update queries on the fly from the list of users and send to the mongo shell:
cat file.csv | awk '{ print("db.users.update({user:\""$1"\"},{ $set:{x:1} }) ") }' | mongo
Option B) mongoimport
Step 1) Import the user list to the database in temporary collection:
mongoimport --type csv -d test -c usersToUpdate --headerline file.csv
file.csv:
userlist
John
Donald
Jeny
Step 2) As soon as the collection is imported you can do as follow:
db.usersToUpdate.find({},{_id:0,userlist:1}).forEach(function(theuser){ db.users.update({username: theuser.userlist}, { $set: { <set some values here> }}); print(theuser+" record updated successfully"); })
Step 3) Finally you can clean the temporary usersToUpdate collection with:
db.usersToUpdate.drop()

Mongo export query

I am doing regex command
mongoexport --host localhost --db testml75spectredb_UK_IRE --collection peoplecollec_UK_IRE --type=csv --out /home/ubuntu/production2.csv -f full_name,headline,linkedin_id,given_name,family_name,url,num_connections,industry,locality,experience.0.organization.0.name -q '{ "headline" : { $regex: / php| javascript| js | ios | android| ruby| rubyonrail| java| laravel| scala| python| django| nodejs| node.js| angularjs| angular.js| devops| fullstack| fullstack| full-stack| C++| C#| WPF| J2EE| golang| objective-c| swift| .NET| reactjs| react.js| backbonejs| backbone.js| .js |symfony2| zend| pyramid| ASP.NET| python| java/i}}'
cause iM looking with people having one of this word in their headline and I have a tons of non relevant document

Just fetch a single attrbute from a single document

I need to pull the latest date from a collection on mongo db and set it in a shell script.
LASTDOCDATE=mongo mongo.com:27017/tracking -u user -p pw --authenticationDatabase authdb --eval 'db.TRACKING_DATA.find({},{datecreated :1}).limit(1).sort({datecreated:-1}).map(function (doc){ return doc.datecreated; })'
echo $LASTDOCDATE
This to be set but when run through the terminal produces:
connecting to: mongo.com:27017/tracking
Mon Jul 27 2015 16:28:08 GMT-0700 (PDT)
have can I pull just the date attribute to be set in a shell script as a variable
Wrap your call with the printjson() method of the shell in order to get an output string:
LASTDOCDATE=mongo mongo.com:27017/tracking -u user -p pw \\
--authenticationDatabase authdb \\
--eval 'printjson(db.TRACKING_DATA.find({},{datecreated :1}).limit(1).sort({datecreated:-1}).map(function (doc){ return doc.datecreated; }))'
Or just print, while referencing the single element:
LASTDOCDATE=mongo mongo.com:27017/tracking -u user -p pw \\
--authenticationDatabase authdb \\
--eval 'print(db.TRACKING_DATA.find({},{datecreated :1}).limit(1).sort({datecreated:-1}).toArray()[0].datecreated'
Notating the single array element, and then the property:
.find({},{datecreated :1}).limit(1).sort({datecreated:-1}).toArray()[0].datecreated'
Or findOne() like this with $orderby:
.findOne(
{ "query": {}, "$orderby": { "datecreated": 1 }},
{ "_id": 0, "datecreated": 1 }
).datecreated
So .print() or .printjson() depending on the output format you want. Or even .valueOf() on the "datecreated" to just get the timestamp value rather than the string.

How to use mongoexport with query script file

I'm trying to follow this tutorial: http://www.ultrabug.fr/tag/mongoexport/
and use a sh file for the query line.
this is my file:
#!/bin/bash
d=`date --date="-3 month"`
echo "{ timeCreated: { "\$lte": $d} }"
this is my mongoexport line:
mongoexport --db game_server --collection GameHistory -query /home/dev/test2.sh --out /home/dev/file.json
I keep getting:
assertion: 16619 code FailedToParse: FailedToParse: Expecting '{': offset:0 of:/home/dev/test2.sh
why? How can I make this work?
I found several errors in your approach, let's examine them one by one.
Date format
MongoDB expects date to be a number or ISO 8601 string.
Unfortunately, unix date utility have no build-in support for this format, so you should use:
d=`date --date="-3 month" -u +"%Y-%m-%dT%H:%M:%SZ"`
Using extended JSON
JSON specification have no support for dates, so you should use MongoDB extended JSON. So, your final query should look like this:
{ "timeCreated": { "$lte": { "$date": "2014-05-12T08:53:29Z" } } }
test.sh output
You messed up with quotation marks. Here is a script example, outputting correct JSON:
#!/bin/bash
d=`date --date="-3 month" -u +"%Y-%m-%dT%H:%M:%SZ"`
echo '{ "timeCreated": { "$lte": { "$date": "'$d'" } } }'
Passing query to mongoexport
mongoexport expects --query to be a JSON string, not .sh script. So, when you're passing file path to --query, mongoexport expects it to be a JSON file.
To fix it you should execute test2.sh yourself and pass resulting string to mongoexport:
mongoexport --db game_server --collection GameHistory \
--query "`./test2.sh`" --out ./test2.json
N.B. Notice " quotation marks around ./test2.sh call. They're telling bash to treat ./test2.sh output as a single parameter, ignoring all inner quotation marks and whitespaces.
You need to add back ticks around a script or command to have it evaluated:
mongoexport --db game_server --collection GameHistory \
-query `/home/dev/test2.sh` --out /home/dev/file.json

mongoexport too many options error while creating changelog

trying to use mongoexport to export a csv of the oplog... tried all quote combinations I have read so far...
../mongodb/bin/mongoexport --csv -d local -c oplog.rs -o export.csv -f {op,ns,o._id} -q "{ts: { \"$gte\": Timestamp(1355100998000,1)} , op :{ \"$nin\" : [\"c\",\"n\"]}"
but I keep getting
ERROR: too many positional options
.....
what could be wrong?
After a lot of screwing around I have tried this
q="{op: { \$nin: [\"c\",\"n\"]}}"
mongoexport --csv -d local -c oplog.rs -o export.csv -f {op,ns,o._id} -q "$q"
and this works like a charm.
but still this
q="{ts: { \$gte: Timestamp(1355100998000,1)}, op: { \$nin: [\"c\",\"n\"]}}"
../mongodb/bin/mongoexport --csv --db local --collection oplog.rs -o changelog.csv --fields op,ns -q "$q"
does not work. Output
Assertion: 10340:Failure parsing JSON string near: ts: { $gte
Feel something is wrong with Timestamp()?
So finally this is how it should be done... or how I did it. It is pretty fast tried it on 30000 records takes max 2 seconds.
All thats happening is that I am storing the results in a new collection by using mongo with --eval option
q="db.oplog.rs.find({ ts : { \$gte : Timestamp( $timestamp, 1)}, op : { \$nin : [\"c\",\"n\"] } }, { op : 1 , ns : 1 , \"o._id\" : 1 , h : 1 } ).forEach(function(x){db.changelog.save(x);})"
../mongodb/bin/mongo localhost:27017/local --eval "$q"
and then export it as .csv using mongoexport
../mongodb/bin/mongoexport --csv --db local --collection changelog -o changelog.csv --fields "o._id","op","ns","h"
and removinf the temporary database to support future changelogs
../mongodb/bin/mongo localhost:27017/local --eval 'db.changelog.remove()'