MongoDb: how to write your mongoDb query result in a file? - mongodb

While running a query i want a result of that query into another file
My query is running successfully in mongo terminal.
db.questions.find({"question" : {$regex : ".*.*"}},{question :1,_id:0,id:1});
{ "id" : 0, "question" : "Amount was debited from my account, but ticket was not
generated. What should I do now?" }
{ "id" : 1, "question" : "How safe is goCash?" }
{ "id" : 2, "question" : "How referral program and goCash works?" }
Now check following image:
here
By this i can write in any type of file by just adding >> filename.extension
Now the main problem is with this one:
When i use find instead of findOne and use a regular expression, it shows unexpected token
Anyone knows how i can modify it to get the desired result.

You are using "(qoutes) inside the command line. Try using {'question' : { \$regex : '.*'}}.
Further the db.collection.find() method returns a cursor. Redirecting it to a file will just write the cursor json.To access the documents, you need to iterate the cursor.
mongo localhost/database -eval "var cursor = {'question' : { \$regex : '.*'}}; while(cursor.hasNext()){ printjson( cursor.next())}"
All the examples in the blog return result as json format.
You can also use any of the mongo-drivers to write your result to a file.

Related

Using upsert with the updateOne() method to perform an update operation

I’m using upsert with the updateOne() method as bellow to perform an update.
db.practice.updateOne(
{“title”:“Night Life”},
{$set: detail},
{upsert: true}
)
My query returns the following:
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("5f8884fed29ded706c3c6737")
}
Below is the detail variable:
let detail = {
“title” : “Night Life”,
“year” : 2021,
“rated” : “PG-13”,
“released” : 2021,
“runtime” : 60,
“countries” : [
“USA”,
“UK”
],
“genres” : [
“comedy”,
“drama”
],
“director” : “Alpha Ly”,
“actors” : [
“Alpha Ly”,
“Kris Dasha”,
“Hope Grace”
]
}
When I check my collection in Compass, I don’t see the document with the ObjectId("5f8884fed29ded706c3c6737
However, when I run the following command db.practice.find({"director": "Alpha Ly"}).pretty(),
it returns the entry I've looking for in Compass.
NB: the number of documents in my collection is still the same as created.
What seems to be the problem here. Why Compass is not displaying the entry?
It seems like I was not using the correct database.
In order to execute the command, I was supposed to use the use command followed by the name of my database to switch to my database. Since I didn't, the update query created another collection and inserted the document there. Therefore, I couldn't find it in my database.
Thanks

multi updating a key along the documents of a collection using pymongo

I have lots of documents inside a collection.
The structure of each of the documents inside the collection is as it follows:
{
"_id" : ObjectId(....),
"valor" : {
"AB" : {
"X" : 0.0,
"Y" : 142.6,
},
"FJ" : {
"X" : 0.2,
"Y" : 3.33
....
The collection has currently about 200 documents and I have noticed that one of the keys inside valor has the wrong name. In this case we will say "FJ" shall be "JOF" in all the docs of the collection.
Im pretty sure it is possible to change the key in all the docs using the update function of pymongo. The problem I am facing is that when I visit the online doc available https://docs.mongodb.com/v3.0/reference/method/db.collection.update/ only explains how to change the values(which I would like to remain how they currently are and change only the keys).
This is what I have tried:
def multi_update(spec_key,key_updte):
rdo=col.update((valor.spec_key),{"$set":(valor.key_updte)},multi=True)
return rdo
print(multi_update('FJ','JOF'))
But outputs name 'valor' is not defined . I thought I shall use valor.specific_key to access to the corresponding json
how can I update a key only along the docs of the collection?
You have two problems. First, valor is not an identifier in your Python code, it's a field name of a MongoDB document. You need to quote it in single or double quotes in Python in order to make it a string and use it in a PyMongo update expression.
Your second problem is, MongoDB's update command doesn't allow you set one field to the value of another, nor to rename a field. However, you can reshape all the documents in your collection using the aggregate command with a $project stage and store the results in a second collection using a $out stage.
Here's a complete example to play with:
db = MongoClient().test
collection = db.collection
collection.delete_many({})
collection.insert_one({
"valor" : {
"AB" : {
"X" : 0.0,
"Y" : 142.6,
},
"FJ" : {
"X" : 0.2,
"Y" : 3.33}}})
collection.aggregate([{
"$project": {
"valor": {
"AB": "$valor.AB",
"FOJ": "$valor.FJ"
}
}
}, {
"$out": "collection2"
}])
This is the dangerous part. First, check that "collection2" has all the documents you want, in the desired shape. Then:
collection.drop()
db.collection2.rename("collection")
import pprint
pprint.pprint(collection.find_one())

Birt report how to write mongodb db command

I want to import report query from js file.
To do that I am choosing Run Database Command command type. But I dont know how to write the query.
I tried sth like this db.user.find({}) blindly but that does not work.
Any doc/resource on using this feature?
If you select Run Database Command you enter a valid JSON-Object in the Expression. This Object will be executed in a call to db.runCommand(), a MongoDB interface to execute Non-CRUD operations.
Enter { isMaster: 1 } and you will see the Result
{
"ismaster" : true,
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2016-04-26T16:24:18.317Z"),
"maxWireVersion" : 3,
"minWireVersion" : 0,
"ok" : 1
}
Update to read the intention of what you want to achieve:
Select the empty line from Command Type and enter the name of the collection you want to use in the line above. Click on $query Expression... and add the JSON-Object to restrict your query. Then select from the displayed attributes the one you want to add to your result set.

Storing a query in Mongo

This is the case: A webshop in which I want to configure which items should be listed in the sjop based on a set of parameters.
I want this to be configurable, because that allows me to experiment with different parameters also change their values easily.
I have a Product collection that I want to query based on multiple parameters.
A couple of these are found here:
within product:
"delivery" : {
"maximum_delivery_days" : 30,
"average_delivery_days" : 10,
"source" : 1,
"filling_rate" : 85,
"stock" : 0
}
but also other parameters exist.
An example of such query to decide whether or not to include a product could be:
"$or" : [
{
"delivery.stock" : 1
},
{
"$or" : [
{
"$and" : [
{
"delivery.maximum_delivery_days" : {
"$lt" : 60
}
},
{
"delivery.filling_rate" : {
"$gt" : 90
}
}
]
},
{
"$and" : [
{
"delivery.maximum_delivery_days" : {
"$lt" : 40
}
},
{
"delivery.filling_rate" : {
"$gt" : 80
}
}
]
},
{
"$and" : [
{
"delivery.delivery_days" : {
"$lt" : 25
}
},
{
"delivery.filling_rate" : {
"$gt" : 70
}
}
]
}
]
}
]
Now to make this configurable, I need to be able to handle boolean logic, parameters and values.
So, I got the idea, since such query itself is JSON, to store it in Mongo and have my Java app retrieve it.
Next thing is using it in the filter (e.g. find, or whatever) and work on the corresponding selection of products.
The advantage of this approach is that I can actually analyse the data and the effectiveness of the query outside of my program.
I would store it by name in the database. E.g.
{
"name": "query1",
"query": { the thing printed above starting with "$or"... }
}
using:
db.queries.insert({
"name" : "query1",
"query": { the thing printed above starting with "$or"... }
})
Which results in:
2016-03-27T14:43:37.265+0200 E QUERY Error: field names cannot start with $ [$or]
at Error (<anonymous>)
at DBCollection._validateForStorage (src/mongo/shell/collection.js:161:19)
at DBCollection._validateForStorage (src/mongo/shell/collection.js:165:18)
at insert (src/mongo/shell/bulk_api.js:646:20)
at DBCollection.insert (src/mongo/shell/collection.js:243:18)
at (shell):1:12 at src/mongo/shell/collection.js:161
But I CAN STORE it using Robomongo, but not always. Obviously I am doing something wrong. But I have NO IDEA what it is.
If it fails, and I create a brand new collection and try again, it succeeds. Weird stuff that goes beyond what I can comprehend.
But when I try updating values in the "query", changes are not going through. Never. Not even sometimes.
I can however create a new object and discard the previous one. So, the workaround is there.
db.queries.update(
{"name": "query1"},
{"$set": {
... update goes here ...
}
}
)
doing this results in:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 52,
"errmsg" : "The dollar ($) prefixed field '$or' in 'action.$or' is not valid for storage."
}
})
seems pretty close to the other message above.
Needles to say, I am pretty clueless about what is going on here, so I hope some of the wizzards here are able to shed some light on the matter
I think the error message contains the important info you need to consider:
QUERY Error: field names cannot start with $
Since you are trying to store a query (or part of one) in a document, you'll end up with attribute names that contain mongo operator keywords (such as $or, $ne, $gt). The mongo documentation actually references this exact scenario - emphasis added
Field names cannot contain dots (i.e. .) or null characters, and they must not start with a dollar sign (i.e. $)...
I wouldn't trust 3rd party applications such as Robomongo in these instances. I suggest debugging/testing this issue directly in the mongo shell.
My suggestion would be to store an escaped version of the query in your document as to not interfere with reserved operator keywords. You can use the available JSON.stringify(my_obj); to encode your partial query into a string and then parse/decode it when you choose to retrieve it later on: JSON.parse(escaped_query_string_from_db)
Your approach of storing the query as a JSON object in MongoDB is not viable.
You could potentially store your query logic and fields in MongoDB, but you have to have an external app build the query with the proper MongoDB syntax.
MongoDB queries contain operators, and some of those have special characters in them.
There are rules for mongoDB filed names. These rules do not allow for special characters.
Look here: https://docs.mongodb.org/manual/reference/limits/#Restrictions-on-Field-Names
The probable reason you can sometimes successfully create the doc using Robomongo is because Robomongo is transforming your query into a string and properly escaping the special characters as it sends it to MongoDB.
This also explains why your attempt to update them never works. You tried to create a document, but instead created something that is a string object, so your update conditions are probably not retrieving any docs.
I see two problems with your approach.
In following query
db.queries.insert({
"name" : "query1",
"query": { the thing printed above starting with "$or"... }
})
a valid JSON expects key, value pair. here in "query" you are storing an object without a key. You have two options. either store query as text or create another key inside curly braces.
Second problem is, you are storing query values without wrapping in quotes. All string values must be wrapped in quotes.
so your final document should appear as
db.queries.insert({
"name" : "query1",
"query": 'the thing printed above starting with "$or"... '
})
Now try, it should work.
Obviously my attempt to store a query in mongo the way I did was foolish as became clear from the answers from both #bigdatakid and #lix. So what I finally did was this: I altered the naming of the fields to comply to the mongo requirements.
E.g. instead of $or I used _$or etc. and instead of using a . inside the name I used a #. Both of which I am replacing in my Java code.
This way I can still easily try and test the queries outside of my program. In my Java program I just change the names and use the query. Using just 2 lines of code. It simply works now. Thanks guys for the suggestions you made.
String documentAsString = query.toJson().replaceAll("_\\$", "\\$").replaceAll("#", ".");
Object q = JSON.parse(documentAsString);

Mongo db : query on nested json

Sample json object :
{ "_id" : ObjectId( "55887982498e2bef5a5f96db" ),
"a" : "x",
"q" : "null",
"p" : "",
"s" : "{\"f\":{\"b\":[\"I\"]},\"time\":\"fs\"}" }
need all documents where time = fs
My query :
{"s":{"time" : "fs"}}
above returns zero products but that is not true.
There are two problems here. First of all s is clearly a string so your query cannot work. You can use $regex as below but it won't be very efficient:
{s: {$regex: '"time"\:"fs"'}}
I would suggest converting s fields to proper documents. You can use JSON.parse to do it. Documents can be updated based on a current value using db.foo.find().snapshot().forEach. See this answer for details.
Second problem is your query is simply wrong. To match time field you should use dot notation:
{"s.time" : "fs"})