Convert MongoDB Find() return information to String with PyMongo - mongodb

I am trying to connect to my Twitter application by fetching the consumer key and access token from a MongoDatabase. I'm relatively new to MongoDB and am still trying to get a handle on things. I need the data as a string, but it's being returned as a cursor. I understand that what I have so far won't be the exact value im looking for, but rather something like
{"value" : "ggggktjjjfr4kf0k04kf0rkforvo"}
but if I could at least get this as a string I could begin to decode it. Any advice would be appreciated.
consumer_key = collection_Authentication.find({"name":"consumer_key"}, {"_id":0, "value":1})
consumer_secret=collection_Authentication.find({"name":"consumer_secret"}, {"_id":0, "value":1})
access_token = collection_Authentication.find({"name":"access_token"}, {"_id":0, "value":1})
access_secret = collection_Authentication.find({"name":"access_secret"}, {"_id":0, "value":1})

Something like:
consumer_key = collection_Authentication.find_one({"name":"consumer_key"})["value"]
Use find_one to get the document immediately. In Python the document is represented as a dict, so retrieve the string by its field name, "value", using brackets: ["value"].

Related

Mongodb shell find to filter and extract embedded text data

I would like to find and extract details from a "stringified" api call which is a field in mongo db document.
The field is like "apiData" field below (only in one long line) which contains both request Headers and a Response Body
as an embedded object - I've separated it out on lines to make it easier to read.
The keys and values are inside "escaped" quotes
a) Can I filter/find based on a selection of header and Response body information
Currently, I'm using a regex e.g. apiData : /5684830/
Is there anything better?
b) extract a selection of header and Response body information from the field string in Mongo by
using build functionality or some else in the mongodb shell v4
Currently, I am exporting the entire field and then processing it.
I was hoping there might be a better way within the mongodb shell.
e.g Example of extract fields/end result
{
"Status Code" : "200 OK"
"numFound\": "56047",
"ebook_count_i": 14,
}
Example of document
{
_id : ObjectId("0000000000000000000000000")
apiData : {
\"Request URL\": \"http://api-call-eg.org/search.json?q=1984\"
\"Request Method\": \"GET\"
\"Status Code\": \"200 OK\"
\"Response Body\" :
{
\"numFound\": \"56047\",
\"start\": \"0\",
\"docs\": [
{
\"cover_i\": \"5684830\",
\"ebook_count_i\": 14,
\"author_name\": [ \"Rand McNally\"],
}
}
}
}
Can I filter/find based on a selection of header and Response body information
Currently, I'm using a regex e.g. apiData : /5684830/
The way you use regex is the perfect solution for the way you have stored your data
extract a selection of header and Response body information from the field string in Mongo by using build functionality or some else in the mongodb shell v4
Unfortunately, you have string. So it's the only option.
But if you can store them as field:value in mongo, you can make use of beautiful aggregation framework where you can do many queries in time efficient manner.

How do I insert an ISODate into mongoDB via Postman?

How do I insert an ISODate into MongoDB via Postman? I have looked around but examples/queries on this subject tend to be just for ways of getting various string formats.
I have an in-house API set up on my localhost so I am querying the database (MongoDB) with Postman. Queries & entries are written in JSON so I would do this like so usually:
{ "adminModifiedId": 1, "dateCreated" : { "$date": "1557510188"}, .., .. }
or
{ "adminModifiedId": 1, "dateCreated" : new Date(), .., .. }
Of course dates within MongoDB are in this format: ISODate("2019-01-21T17:41:27.107Z") but I just can't find the right solution here. I know that Postman does allow to set global & environmental variables within the Pre-request Script section but it does seem strange that a platform so established would not have a way to format or convert into an ISODate type.
Edited in response to #Danny_Dainton
Postman body as JSON request
Pre-request Script
Erorr response
I'll leave this for a few days to see if anyone can suggest a pre-established answer (that doesn't require a pre-request script). Otherwise I will mark mine correct as the only answer that has worked for me so far.
You could use either of these methods in a Pre-request Script.
Using the moment lib, like this:
var moment = require('moment')
pm.globals.set("ISO_Date", moment())
More info about that here: https://stackoverflow.com/a/47823708/6028443
Or
Just use basic JS code like this to create the same timestamp:
pm.globals.set("ISO_Date", (new Date()).toISOString())
Once the variable is created, add {{ISO_Date}} reference to your request body.
For whatever reason other solutions didn't work for me but may for others. This one resolved my issue though so may be of use.
Pre-request Script
let t = Date.now()
pm.environment.set('t', t);
Body (sample)
{ "adminModifiedId": 1, "dateCreated" : { "$date": {{t}}}, .., .. }

Transforming DB Collections in Meteor.publish

Hopefully this question is not too long but I am trying to include as much details as possible in what I did..
I am trying to figure out how to implement logic in Meteor.publish() that takes data from the DB, changes all the values in a column and makes the updated collection available for client-side subscription.
Specifically, I have a table that stores messages between users and the recipient is identified by his userId. I would like to replace the userId with his actual phone number which should be available in the Meteor.users table.
When I looked it up online I saw suggestions to use transform but my understanding is that it's not reactive.. I then learned about map but discovered that it returns an array which breaks the Meteor.publish() method. Finally I found something that uses forEach and self.added() and self.ready() so my code currently looks like this:
Meteor.publish("myMessages", function () {
var self = this;
Messages.find({
$or: [
{ senderId: this.userId },
{ recipientId: this.userId }
]
}).forEach(function(m) {
m.recipientId = Meteor.users.findOne({ _id: m.recipientId }).username;
console.log("adding msg to collection:");
console.log(m);
self.added("Messages", m._id, m);
});
self.ready();
});
The log messages look right and when Meteor restarts it prints all the messages from the DB related to the user where the recipient is replaced correctly with the phone number. However, on the client side when I try to run Messages.findOne(msgId) (with an id I verified exists by selecting it directly in mongo shell) I get undefined back and furthermore, running Messages.find() through developer tools in the browser returns undefined as well although I expected the messages that showed up in the logs to be available..
I feel that this is a basic use case but I am not able to make this work.. any help is appreciated!
"You can transform a collection on the server side like this:"
https://stackoverflow.com/a/18344597/4023641
It worked for me.
Unfortunately, changes in users collection will not update reactively these custom fields.

how to Restfully implement joins via a query string

Our stack currently uses mongoose as a ODBM and I was wondering how exactly I should implement a RESTFUL request to determine whether a foregin key gets populated(i.e the forgeign key _id property gets replaced with the either the entire document or part of the document from another collection).
I know I could send up something like
?populate=CollectionName&populateFields=fieldsnames`
via a query string but something about that seems hacky to me and I was wondering what's considered the standard/best practice in this situation
MongoDb doesn't have joins. If the associated data is small enough, then it's suggested to embed the document.
If you take that appoarch, then you could perform this simple query to check if the embedded document field is a document.
0 < db.products.count({_id : 3, rebateProgram : { $type : 3} })
In mongoose, I think it's
0 < productModel.find({}).where({_id : 3, rebateProgram : { $type : 3} }).count()
rebateProgram : {$type : 3} means only match the rebateProgram field if it's an with an embedded document.
3 is the BSON type for embedded document.
RESTful URL
A restful url to check the a property on a document could look like this.
The request would be a GET because you're retrieving a value and not modifying anything data.
GET: /??/:collectionName/:documentId/action
Example:
Request:
GET: /api/products/3/status?hasObject=rebateProgram
Response:
{
id: 3,
hasObject : { rebateProgram : true },
success : true,
errMsg : ""
}
However if it's always going to be the same field you're checking for, then include the status of the embedded field in the response.
Like this.
Example:
Request:
GET: /api/products/3/status
Response:
{
id: 3,
hasValidRebateProgram : true,
success : true,
errMsg : ""
}
More info:
Doc: BSON spec
Allowing query parameters that lets the client add or remove fields returned by a resource's endpoint is not hacky in my opinion. I recommend reading this article on RESTful best practices. So your URL would look something like this:
Assuming you're talking about a GET route
GET /users/:user_id?fields=field1,some_other_field
You shouldn't need to represent your database in a RESTful URL. Think from a client's perspective. What would make sense to you if you didn't design the database? I think an API should expose behavior, not a database.

Graph API - get JSON data without "paging" key

I'm getting facebook data using graph api, adding fields in string and get JSON result.
Example:
https://graph.facebook.com/me?fields=music
But JSON returned contains a "paging" key and I do not I want this key.
{ "music":{
"data":[
{
"name":"",
"category":"",
"id":"",
"created_time":""
},
{
"name":"",
"category":"",
"id":"",
"created_time":""
}
],
"paging":{
"next":"https://graph.facebook.com/me?fields=music&method=GET&metadata=true&format=json&callback=___GraphExplorerAsyncCallback___&access_token=...&limit=5000&offset=5000&__after_id=..."
}}}
EDITED:
I'm using Java API (restfb.com) to get JSON.
The command in java is:
FacebookClient client = new DefaultFacebookClient("ACCESS_TOKEN_HERE");
JsonObject rMusic = client.fetchObject("ID_HERE", JsonObject.class, Parameter.with("fields", "id,name,religion,birthday,music"));
How do I avoid it or remove it?
When you have your Javascript object built from the JSON, just pay attention to the array of data: result.music.data
And forget about the paging property: result.music.paging
Remember, there's no law in coding that you have to look at every property in your scripts.
Based upon the edit to the question above, here's a new answer.
The Rest API is deprecated. You should upgrade your app to use the Graph API as this is the one being supported.
Also, if you see a property you don't like, you don't have to access it. Remember, there's no law in coding that you have to look at every property in your scripts.