How to query through a DBRef in MongoDB/pymongo? - reference

Is it possible to query through a DBRef using a single find spec?
user collection
{
'age': 30
}
post collection
{
'user': DBRef('user', ...)
}
Is it possible to query for all post who's users are 30 in a single find step? If not, would it be wise to create a javascript function to handle the multi-stage operation or will that cause blocking problems?

it's not possible to do that. i would recommend either:
a) changing your data model so that all of the data is in a single document (might not be possible depending on your case).
b) querying for users who are 30 first, and then doing a second query to get posts where user is $in that list. i would do this client side rather than using server-side JS or anything like that.

I use a Python driver, so forgive my not-so-mongodb syntax:
users = list(db.Users.find({'Age':30}))
posts = list(db.Posts.find({'User':{'$in':users}}))

Install python bson package. and try as example.
import pymongo
from pymongo import MongoClient
from bson.dbref import DBRef
client = MongoClient('ip', 27017)
client.the_database.authenticate('user', 'password', source='db_name')
db = client['db_name']
user = db['user']
user_id = user.find_one({'email': 'xxxxx#gmail.com'}).get('_id')
client_user_relation = db['client_user_relation']
print(client_user_relation.find_one())
print(user_id)
print(DBRef(collection = "user", id = user_id))
print(client_user_relation.find_one({'user': DBRef(collection = "user", id = user_id)}))

Related

Dynamic Mongoose Field Type

I am developing an app where a user could store his model on a database using mongoDB and mongoose. Taken from mongoose tutorial the type of the field has to be defined. For example here we have to define that the name is a string.
const personSchema = new mongoose.Schema({
name: String
});
const Person = mongoose.model('Person', personSchema);
Is there any way to make it dynamic to user's input. I want to create a form where a user will enter a field name and select one of the field types that Mongoose offers [String,Number,Date etc], but I cannot figure any way to implement it. To be honest I don't know even if this is a good approach. An alternative would be to pass everything as a String and serialise the input in order to store it. I want to achieve something like that:
const {fieldName,fieldType} = userInput;
const customSchema = new mongoose.Schema({
fieldName: fieldType
});
const CustomModel = mongoose.model('CustomSchema', customSchema);
Is this possible or should I implement another approach? An alternative would be to pass everything as a String and serialise the input in order to store it.
Thank you in advance!
If I understand you correctly it should work like that:
User defines the model to store
Schema is created using the data provided by the user
User can pass the data to store using the previously created model which will validate the user's input later
In fact, I'm working on a project that has the same functionality. Here is how we did it.
A user sends the model and we store it as a string since we need to have the ability to create the model once again.
When the user passes new data to store using the created model we get the string from mongo and parse it to create the schema. This operation is relatively easy (but depends on what you want to achieve as it can get tricky if you want to have some advanced validation) as you have to just create an object with correct values from mongoose. Something like this for every field that the user has defined.
export const fieldConverter = ({name, type}) => {
switch (type) {
case 'String':
return { [name]: String };
case 'Number':
return { [name]: Number };
...
}
When you have your object ready then you can create a model out of it.
The line with accessing your model from mongoose.models is important as the mongoose will cache the model and throw an error if you try to create it once again.
const DatasetModel =
mongoose.models["your-model-name"] ??
mongoose.model("your-model-name", new mongoose.Schema(schema));
Now when you have the model the rest is just like with the normally created one.
This approach worked for us so I'm adding this as inspiration maybe it will help you. If you have any specific questions about the implementation feel free to ask I will be happy to help.
There is also a Mixed type in mongoose if you don't need the validation later. You can check it here: https://mongoosejs.com/docs/schematypes.html#mixed
You can use Schema.Types.Mixed, An "anything goes" SchemaType. Mongoose will not do any casting on mixed paths.
let customSchema = new Schema({custom: Schema.Types.Mixed})
Read more about it here
After some research I figure at that mongoose type can also be strings. For example
const personSchema = new mongoose.Schema({
name: "String"
});
const Person = mongoose.model('Person', personSchema);
Mongoose will handle it

How to put an object inside another object in firebase database programmatically?

I'm setting up a firebase database for handling some requests I receive from my application. I need to insert an object "player" inside another object "room" to handle the multiplayer lobbies.
For a better comprehension I also do a little schema using firebase realtime db - schema below.
I want that instead of "room 1" the database puts an unique id, same thing for "player 1" and the other. Do you have any advice to help me doing this?
]
Try this (using a "path" to point to where you need):
const updates = {}
const roomName = 'room1'
const playerName = 'player1'
const path = `chip-chop/rooms/${roomName}/${playerName}`
const playerData = {
name: 'marco',
points: 0,
}
updates[path] = playerData
await firebase.database().ref().update(updates)
Please note that this will update the data. This means that other fields will not be affected (whether that is a bad or good thing is up to you)

How can I insert one document/row in mongodo using pymongo in django views.py file? using post method

I have connected one mongo db using below connections and I am trying to insert one record/row/document in that db using post method but I am so confused how to do that by below scenario.
"By post method check if the record already present or not if not then
create a record"
This is how I made connection and connection successfully made. the fields in dcollection are id, firstname, lastname, student_id
I want to do this.
"By post method check if the record already present or not if not then
create a record".
import pymongo
from pymongo import MongoClient
db_name = 'student_db'
client = MongoClient('localhost', 27017)
db_obj = client[db_name]
collection=db_obj['mongo_app_student']
Mongo has an awesome set of upsert commands like replace_one, replace_many
see another great post about it and, of course, -> mongo docs
see below example, hope this is what you're looking for
client = MongoClient('localhost', 27017)
db = client.student_db
collection = db.mongo_app_student
collection.insert_one({"name":"vladimir"})
for document in collection.find():
pprint(document)
Merge command
obj1 = {"name":"Vladimir"} # V in upper case here
collection.update_one( { "name" : obj1["name"] } , {"$set":obj1} , True ) # True means Upsert
obj2 = {"name":"Being Human"}
collection.update_one( { "name" : obj2["name"] } , {"$set":obj2} , True ) # True means Upsert
for document in collection.find():
pprint(document)
another example from pymongo docs
obj1 = {"name":"Vladimir"}
obj2 = {"name":"Being Human"}
requests = [ReplaceOne({"name" : obj1["name"]}, obj1, upsert=True),ReplaceOne({"name" : obj2["name"]}, obj2, upsert=True)]
result = collection.bulk_write(requests)
result.modified_count

Mongoose find data from dynamic Collection

I am new to MongoDB & working on a MEAN application.
In the mongo database(I am using mongoose), the collections are adding dynamically from third party API like schoolList1,schoolList2,schoolList3,schoolList4,....
I am facing problem to find a solution to get data from collections, Like If a user sends the argument from FrontEnd to find data from schoolList3.
The find function should apply on that collection only & return the data.
I am unable to solve it that how should I get data without passing schema and did not get any other way.
Set collection name option for your schema from user's input:
var collectionName = 'schoolList3'; // set value from the input
var dataSchema = new Schema({/** your schema here **/}, { collection: collectionName });

Log specific postgresql query using pg-promise

I am using pg-promise package with Nodejs to execute PostgreSQL queries. I want to see the queries executed. Only specific queries, say, just one query that I want to debug.
I can see that one recommended way is to use the pg-monitor to catch the events and log them as mentioned here in the examples documentation.
Without using pg-monitor, is there a simple way to just print the prepared query that is executed. I can't see it in the docs.
Example:
db.query("SELECT * FROM table WHERE id = $/id/", {id: 2})
How to print this query to yield?
SELECT * FROM table WHERE id = 2
is there a simple way to just print the prepared query that is executed...
A query in general - yes, see below. A Prepared Query - no, those are by definition formatted on the server-side.
const query = pgp.as.format('SELECT * FROM table WHERE id = $/id/', {id: 2});
console.log(query);
await db.any(query);
And if you want to print all queries executed by your module, without using pg-monitor, simply add event query handler when initializing the library:
const initOptions = {
query(e) {
console.log(e.query);
}
};
const pgp = require('pg-promise')(initOptions);

Resources