Traditional SQL vs MongoDB/CouchDB for simple python app - python

Say I got an traditional SQL structure like so:
create table tags (id PRIMARY KEY int, tag varchar(100));
create table files (id PRIMARY KEY int, filename varchar(500));
create table tagged_files (tag_id int, file_id int);
I add some tags:
insert into table tags (tag) values ('places');
insert into table tags (tag) values ('locations');
And some files:
insert into table files (filename) values ('/tmp/somefile');
insert into table files (filename) values ('/tmp/someotherfile');
and then tag these files:
insert into table tagged_files (tag_id, file_id) values (1,1);
insert into table tagged_files (tag_id, file_id) values (1,2);
Then I can find all the files tagged with the first tag like so:
select * from files, tagged_files where id = file_id and tag_id = 1
But how do I do the same thing using NoSQL solutions like MongoDB and CouchDB?? And what NoSQL project is best suited for something like this?

For MongoDB.
Chances are you'd simply save them with the tags as:
db.Files.save({ "fn" : "/tmp/somefile", "ts" : [ { "t" : "places" }, { "t" : "locations" }] });
db.Files.save({ "fn" : "/tmp/someotherfile", "ts" : [ { "t" : "locations" }] });
Alternative is to save tags separately (ObjectId's are 12 bytes iirc):
db.Tags.save({ "t" : "places" });
db.Tags.save({ "t" : "locations" });
db.Files.save({ "fn" : "/tmp/somefile", "t" : [ { "i" : ObjectId("IdOfPlaces") }, { "i" : ObjectId("IdOfLocations") }] });
In both cases to get a file it's
db.Files.find({ "_id" : ObjectId("4c19e79e244f000000007e0d") });
db.Files.find({ "fn" : "/tmp/somefile" });
Or a couple files based on tags:
db.Files.find({ ts : { t : "locations" } })
db.Files.find({ t : { i : ObjectId("4c19e79e244f000000007e0d") } })
Examples are from the mongo console. And if you store tags with Id's you'd obviously have to read the tags up based on the Id's once you got the file(s).

Related

Extracting and updating a dictionary from array of dictinaries in MongoDB

I have a structure like this:
{
"id" : 1,
"user" : "somebody",
"players" : [
{
"name" : "lala",
"surname" : "baba",
"player_place" : "1",
"start_num" : "123",
"results" : {
"1" : { ... }
"2" : { ... },
...
}
},
...
]
}
I am pretty new to MongoDB and I just cannot figure out how to extract results for a specific user (in this case "somebody", but there are many other users and each has an array of players and each player has many results) for a specific player with start_num.
I am using pymongo and this is the code I came up with:
record = collection.find(
{'user' : name}, {'players' : {'$elemMatch' : {'start_num' : start_num}}, '_id' : False}
)
This extracts players with specific player for a given user. That is good, but now I need to get specific result from results, something like this:
{ 'results' : { '2' : { ... } } }.
I tried:
record = collection.find(
{'user' : name}, {'players' : {'$elemMatch' : {'start_num' : start_num}}, 'results' : result_num, '_id' : False}
)
but that, of course, doesn't work. I could just turn that to list in Python and extract what I need, but I would like to do that with query in Mongo.
Also, what would I need to do to replace specific result in results for specific player for specific user? Let's say I have a new result with key 2 and I want to replace existing result that has key 2. Can I do it with same query as for find() (just replacing method find with method replace or find_and_replace)?
You can replace a specific result and the syntax for that should be something like this,
assuming you want to replace the result with key 1,
collection.updateOne({
"user": name,
"players.start_num": start_num
},
{ $set: { "players.$.results.1" : new_result }})

MongoDB check if list item exists for an item in collection before inserting to DB

Im developing a django application uisng python and mongoDB. Im developing a form and take user inputs and save to DB.
Before inserting i want to check if data is already present DB.
I have a mongo collection which looks something like below :
coll_1 :
{ "_id" : ObjectId("56e0a3a2d59feaa43fba49d5"), "timestamp" : ISODate("2017-11-18T10:23:29.620Z"), "City_list" : "[PN-City1, PN-City2,PN-City3, PN-City4]", "LDE" : "LDE-1234, LDE-345, LDE-456" , "Name": "ABC"}
{ "_id" : ObjectId("56e0a3a2d59feaa43fba49d6"), "timestamp" : ISODate("2016-12-18T10:23:29.620Z"), "City_list" : "[PN-City4, PN-City5,PN-City6,PN- City7]", "LDE" : "LDE-444, LDE-3445, LDE-456", "Name": "BCD"}
{ "_id" : ObjectId("56e0a3a2d59feaa43fd67873"), "timestamp" : ISODate("2016-12-18T10:23:29.620Z"), "City_list" : "[PN-City1, PN-City6,PN-City9,PN- City10]", "LDE" : "LDE-444, LDE-3445, LDE-456", "Name": "XYZ"}
I have a form from where i take user inputs : Name, Cities (one or more comma separated), LDE (comma separated)
In my script i want to check before inserting into mongodb
If the user is new user insert directly db.
If old user, check if cities inputed by user is present in db already if not update db else throw a messagee to html with message saying city already present in DB.
Say my input is something like this :
Name: PQR
City_list : PN-City4, PN-City12
LDE: LDE-6767
My code is as below :
if 'Name' in pdata and ('city_list' in pdata and re.match("(PN-\w*-\d)(PN-\w*-\d)*", pdata['city_list'])):
user_input = pdata['city_list'].split(",")
pname = pdata['Name']
for data in user_input:
if db.coll_1.find({"Name": pname , 'City_list': { "$in": data}})
This is giving me error.
How do i achieve this
I tried something like this :
for data in user_input:
data = str(data) # it was taking as unicode
if (db.coll_1.find({"Name": pname , 'City_list': { "$in": data}}).count() > 0):
Gives error : OperationFailure: $in needs an array
CIty_list is a string
Can some one please help me with this

Delete a list item from an Embedded Document MongoEngine

I'm having trouble to find the way to delete a list item inside an Embedded document using mongo engine.
Document structure:
{
"_id" : "id",
"user" : ObjectId("xxxxxxx"),
"invoice" : false,
"coupon" : ObjectId("xxxxxxx"),
"date" : ISODate("2017-03-31T11:32:57.467Z"),
"orders" : [
{
"products" : [
ObjectId("xxxxxxx")
]
}
],
"shipping_address" : {
},
}
Using this structure, what I want to achieve, is to delete the id inside the products list inside the orders embedded document.
Any idea? any help would be really appreciated

Deleting a row from an embedded document in mongo engine

I have a document called login_info. It has two fields:
name
password
Location
Location is an embedded document with two fields:
datetime
city
There are datas in the embedded document and i want to delete a row from it.
for eg: i have to delete all the rows with location "Canada". How can i do this in mongo engine ? any help
Try this
db.login_info.update({}, {$pull:{location:{city:"Canada"}}})
Ok try this instead
db.login_info.update( { "location.city" : { $exists : true } }, { $unset : { "location.city" : "Canada" } }, false, true);
This will remove all "rows" where city is "Canada".

adding a list field in mongo (python)

I have an id which some tags are associated with and I want to fill a collection with those tags. How do I do this?
Suppose I have the following:
key: 12345, tags = ["foo","bar","foobar"]
So I am hoping to get a document in a collection named "Tags" like this:
{
"_id" : ObjectId("4fbaa6076a56b2700d000000"),
"key" : 12345,
"tags" : ["foo","bar","foobar"]
}
How do I do this in python?
mongo_conn.Tags.insert({
"key": 12345,
"tags": ["foo","bar","foobar"]
})

Categories

Resources