I would like some help with flask, pymongo and some ideas.
What I want to do:
I have a list:
lg=[{'name_dep': name_dep, 'cod_prg': cod_prg, 'name_prg': name_prg,
'cod_form': cod_form, 'an_s': frm['an_s'], 'serie': serie,
'nr_s':frm['nr_s'], 'nr_gr': frm['nr_gr'], 'nr_sgr': frm['nr_sgr']}]
where frm=mongo.db.colecttion1
I want to create a temporary collection of which documents have the structure:
{
"_id" : ObjectId("576d3494b7e8f8d6d0d7d0e6"),
"name_dep" : "name_dep1",
"cod_prg" : "cod1",
"an_s" : "1",
"name_prg" : "name1",
"forms" : [
{
"nr_gr" : "5",
"nr_sgr" : "10",
"nr_s" : "150"
}
{
"nr_gr" : "6",
"nr_sgr" : "12",
"nr_s" : "90"
}
{
"nr_gr" : "2",
"nr_sgr" : "4",
"nr_s" : "50"
}
],
"cod_form" : "1",
"serie" : "XX"
}
The code for achieving that is:
if mongo.db.form_temp:
mongo.db.form_temp.drop()
coll_temp=mongo.db.form_temp
formatie1=lg[0]
coll_temp.insert({'name_dep':formatie1['name_dep'], 'cod_prg':formatie1['cod_prg'], 'name_prg':formatie1['name_prg'], 'cod_form':formatie1['cod_form'], 'an_s':formatie1['an_s'], 'serie':formatie1['serie'], 'forms':[{'nr_s':formatie1['nr_s'], 'nr_gr':formatie1['nr_gr'], 'nr_sgr':formatie1['nr_sgr']}]})
for y in range (1, len(lg)-1):
x=lg[y]
dep_in_coll=mongo.db.coll_temp.find_one({ '$and': [{'name_dep':x['name_dep']}, {'cod_prg':x['cod_prg']}]})
if dep_in_coll is None:
coll_temp.insert({'name_dep':x['name_dep'], 'cod_prg':x['cod_prg'], 'name_prg':x['name_prg'], 'cod_form':x['cod_form'], 'an_s':x['an_s'], 'serie':x['serie'], 'forms':[{'nr_s':x['nr_s'], 'nr_gr':x['nr_gr'], 'nr_sgr':x['nr_sgr']}]})
else:
iddoc=dep_in_coll['_id']
listforms=dep_in_coll['forms']
listforms.append([{'nr_s':x['nr_s'], 'nr_gr':x['nr_gr'], 'nr_sgr':x['nr_sgr']}])
dep_in_coll.update({'_id':iddoc}, {'$set' : {'forms': listforms}})
What I'doing is to drop the temporary collection if exists and then to create the collection again and insert the first element of the list lg.
Then iterate through the lg list and for each the same values of the pair name_dep , cod_prg modify the forms list by adding the fields nr_s, nr_gr, nr_sgr with their values.
My code doesn't run as expected, but inserting the documents in the temp collection, the collection having the same no. of documents as lg list, without modifying the forms list.
Thank you.
Related
I am trying to upsert array elements for a single document.
I want to provide list of objects to mongo query, and for each object if exists (based on some field) in an mongo document array, replace the object in the array, if not exists, add it to the array.
I know this can be done using application side, but can this be done using 1 transactional query?
example:
{
"_id" : ObjectId("50b429ba0e27b508d854483e"),
"array" : [
{
"id" : "1",
"letter" : "a"
},
{
"id" : "2",
"letter" : "b"
},
{
"id" : "3",
"letter" : "c"
}
],
"tester" : "tom"
}
Now, I want to pass to pass to my query the following objects:
{
"id" : "3",
"letter" : "c-new"
"newField": "some string"
},
{
"id" : "4",
"letter" : "D"
}
Based on id field I want mongo to see that:
id:3 already exists, so it will replace the current element with the new object provided
id:4 doesn't exists, so it will add it to the array elements.
(that's basically called upsert).
I am pretty new to mongodb, and I am not able to query in my mongo collection.
Structure :
"chapterId":1,
"videos" : [
{
"videoId" : "1",
"videoName" : "about",
"duration" : "12:36",
"tags":["business", "design"]
},
{
"videoId" : "2",
"videoName" : "course",
"duration" : "04:00",
"tags":["technology", "design"]
}
]
I need to select all videos with the tag "business" in chapterId 1.
Can this be done without changing the structure of my collection ?
You should use aggregation so below query will help you
db.collectionName.aggregate(
{"$unwind":"$videos"},
{"$match":{"chapterId":1,"videos.tags":"business"}}
)
I was wondering how I can query from an embedded document inside an array. I have following structure:
{ "targetId" : 2, "metaData" : [ { "key" : "id", "value" : 1 }, { "key" : "name", "value" : "Parisa" }, { "key" : "img", "value" : { "imgid" : 1, "imgName" : "img1" } } ]
I could search simple key-values like key = id and value =1, but I could not search based on the values with embedded document e.g. key="img"
I tried following query but it does not work:
db.test.find({"metaData":{$elemMatch:{"key":"img", "value":{"imgid":1}}}})
Could you please help me!
I think the "value" part of your query is a little off. You need to put the document element in the criteria:
b.test.find({"metaData":{$elemMatch:{"key":"img", "value.imgid":1}}})
I have two MongoDB collections: The first is a collection that includes frequency information for different IDs and is shown (truncated form) below:
[
{
"_id" : "A1",
"value" : 19
},
{
"_id" : "A2",
"value" : 6
},
{
"_id" : "A3",
"value" : 12
},
{
"_id" : "A4",
"value" : 8
},
{
"_id" : "A5",
"value" : 4
},
...
]
The second collection is more complex and contains information for each _id listed in the first collection (it's called frequency_collection_id in the second collection), but frequency_collection_id may be inside two lists (info.details_one, and info.details_two) for each record:
[
{
"_id" : ObjectId("53cfc1d086763c43723abb07"),
"info" : {
"status" : "pass",
"details_one" : [
{
"frequency_collection_id" : "A1",
"name" : "A1_object_name",
"class" : "known"
},
{
"frequency_collection_id" : "A2",
"name" : "A2_object_name",
"class" : "unknown"
}
],
"details_two" : [
{
"frequency_collection_id" : "A1",
"name" : "A1_object_name",
"class" : "known"
},
{
"frequency_collection_id" : "A2",
"name" : "A2_object_name",
"class" : "unknown"
}
],
}
}
...
]
What I'm looking to do, is merge the frequency information (from the first collection) into the second collection, in effect creating a collection that looks like:
[
{
"_id" : ObjectId("53cfc1d086763c43723abb07"),
"info" : {
"status" : "pass",
"details_one" : [
{
"frequency_collection_id" : "A1",
"name" : "A1_object_name",
"class" : "known",
**"value" : 19**
},
{
"frequency_collection_id" : "A2",
"name" : "A2_object_name",
"class" : "unknown",
**"value" : 6**
}
],
"details_two" : [
{
"frequency_collection_id" : "A1",
"name" : "A1_object_name",
"class" : "known",
**"value" : 19**
},
{
"frequency_collection_id" : "A2",
"name" : "A2_object_name",
"class" : "unknown",
**"value" : 6**
}
],
}
}
...
]
I know that this should be possible with MongoDB's MapReduce functions, but all the examples I've seen are either too minimal for my collection structure, or are answering different questions than I'm looking for.
Does anyone have any pointers? How can I merge my frequency information (from my first collection) into the records (inside my two lists in each record of the second collection)?
I know this is more or less a JOIN, which MongoDB does not support, but from my reading, it looks like this is a prime example of MapReduce.
I'm learning Mongo as best I can, so please forgive me if my question is too naive.
Just like all MongoDB operations, a MapReduce always operates only on a single collection and can not obtain info from another one. So you first step needs to be to dump both collections into one. Your documents have different _id's, so it should not be a problem for them to coexist in the same collection.
Then you do a MapReduce where the map function emits both kinds of documents for their common key, which is their frequency ID.
Your reduce function will then receive an array of two documents for each key: the two documents you have received. You then just have to merge these two documents into one. Keep in mind that the reduce-function can receive these two documents in any order. It can also happen that it gets called for a partial result (only one of the two documents) or for an already completed result. You need to handle these cases gracefully! A good implementation could be to create a new object and then iterate the input-documents copying all existing relevant fields with their values to the new object, so the resulting object is an amalgamation of the input documents.
I've got this structure of document, saved in MongoDB 2.6.1, running on Linux:
{
"_id" : "1",
"name" : "Level0",
"childs" : [
{
"id" : "2",
"name" : "Level1",
"childs" : [
{
"id" : "3",
"name" : "Level2",
"childs" : [
{
"id" : "4",
"name" : "Level3-1",
},
{
"id" : "5",
"name" : "Level3-2",
}
]
}
...
Every Element got his childs and every child-element got his own childs until the technical end.
Now I want to Query my MongoDB with something like:
db.categories.find({'childs':{$elemMatch:{$all:['Level19-23']}}})
This Query dont work by the way.
What is a good query to get my elements?
I dont know anything about the children or parents, I've got only the name of the element, and I need the element with all his children.
Anyone got an advise for me, the MongoDB Newbe? :)
Thanks in advance!