Mongo projection result as an array of selected items - python

For the given documents in the mongo
{"_id" : "joe":
grocerylist: [ "cheddar", "apple", "oranges" ]
}
{"_id" : "joanna":
grocerylist: [ "cheddar", "foobar" ]
}
{"_id" : "john":
grocerylist: [ "apple", "oranges" ]
}
If I search for user with cheddar in their list
find({"grocerylist" : cheddar}, fields={'_id' : 1})
I get
[{u'_id': u'joe'}, {u'_id': u'joanna'}]
Using Mongo, how can I get just a list of matched users, like this..
[u'joe', u'joanna']
Thanks.

_ids are unique across the collection, thus you can use distinct here.
collection.distinct('_id', {'grocerylist' : cheddar})

One option would be to use a list comprehension:
cursor = db.col.find({"grocerylist" : cheddar}, fields={'_id' : 1})
print([document['user'] for document in cursor])

Related

How to find strings with matched letters in list/array using lambda function?

I am using lambda function, python 3.6 and Mongodb atlas. In mongodb i have one collection below like this. collection name profile. below as the collection structure.
"_id" : ObjectId("5db234df92b0ce00016932f3")
"username" : "testing"
"channel" : [ "abc", "efg", "cde", "xyz" ]
"about" : "this is a test case"
we have multiple rows similar to the above. Now i am using python, i write the lambda function to find strings matched letter in channel array.find the below lambda function.
profile = db.profile
name = event['cname']
ch = list(profile.aggregate([{
"$match" : { "username" : "testing" }
},
{
"$project" : {
"channel" : 1
}
}
]))
ch1 = json.loads(json.dumps(ch, default=json_util.default))
ch2 = [document["channel"] for document in ch1]
new_list = []
for i in ch2:
if(re.findall(name, i)):
new_list.append(i)
return new_list
I have passed "cname" : "c" in event. but i am getting error like this.
Response:
{
"errorMessage": "expected string or bytes-like object",
"errorType": "TypeError",
"stackTrace": [
[
"/var/task/lambda_function.py",
51,
"lambda_handler",
"if(re.findall(search, i)):"
],
[
"/var/lang/lib/python3.6/re.py",
222,
"findall",
"return _compile(pattern, flags).findall(string)"
]
]
}
I tried with re.search also but i am getting same, I need output like this below.
Input: "cname" : "c"
output: "abc"
"cde"
can you please help me with solution, thanks on advance.
Follow the below code:
ch2 = [document["channel"] for document in ch]
new_list = []
for word in ch2[0]:
print(word)
if(re.findall(name, word)):
new_list.append(word)
return new_list
the issue has been resolved

PyMongo iterate through documents / arrays within documents, replace found values

I have the following data in Mongodb:
{ "_id" : 1, "items" : [ "apple", "orange", "plum" ] }
{ "_id" : 2, "items" : [ "orange", "apple", "pineapple" ] }
{ "_id" : 3, "items" : [ "cherry", "carrot", "apple" ] }
{ "_id" : 4, "items" : [ "sprouts", "pear", "lettuce" ] }
I am trying to make a function using Python / PyMongo that takes 2 arguments, an old and a new string. I would like to find all the "apple" in all of the arrays across all of the documents and replace them with the string "banana".
Below is the code I have so far:
def update(old, new):
for result in db.collection.find({"items" : old}):
for i in result["items"]:
if i == old:
db.collection.update({"_id": result["._id"]}, {"$set": {"items": new}})
Finally figured this out, it is actually really simple:
from pymongo import MongoClient
mongo_client = MongoClient(127.0.0.1, 27017)
db = mongo_client.my_databse
def update(old, new)
for result in db.collection.find({'items' : old}):
db.collection.update_one({ '_id': result['_id'], 'items': old}, { '$set' : {'items.$' : new}})
use update_many() to update multiple documents in one query instead of looping through the documents.
from pymongo import MongoClient
mongo_client = MongoClient(127.0.0.1, 27017)
db = mongo_client.my_databse
def update(old, new)
db.collection.update_many({'items': old}, { '$set' : {'items.$' : new}})
For pymongo less than 3.2 use update with multi flag
def update(old, new)
db.collection.update({'items': old}, { '$set' : {'items.$' : new}}, multi=True)

How to create a custom dictionary in python?

There is what i have in source:
"VirtualizationType": "hvm",
"Tags": [
{
"Value": "Test",
"Key": "Name"
}
]
and here is a bit of my code:
for item in result:
temp = {"Tags": item["Value"], "VirtualizationType": item["VirtualizationType"]}
output.append(temp)
I can easily export VirtualizationType but couldn`t do it with Tags
An example of how to create a dictionary in Python, from docs:
tel = {'jack': 4098, 'sape': 4139}
In this example jack, snape are the keys and 4098, 4139 are the values.
Values can also be strings and a list of dictionary like in your case,
your code can modified into this:
dictionary = {"Virtualization Type" : "hvm", "Tags" : [{"Value" : "Test", "Key" : "Name"}] } #Runs in the python interpreter with no errors

Json parse python error

I have the following dict. I would like to loop through this key and values
i.e for items in ice/cold, print "values"
[
{
"ice/cold": [
"vanilla",
"hotchoc",
"mango",
"banana"
]
},
{
"fire/hot": [
"barbecue",
"hotsalsa",
"sriracha",
"kirikiri"
]
},
{
"friendly/mild": [
"ketchup",
"mustard",
"ranch",
"dipster"
]
}
]
Tried this:
data='*above set*'
for key in data.items():
print value
but gives me error
AttributeError: 'list' object has no attribute 'items'
The data structure you have is a bit strange. You don't have a single dict, you have a list of dicts, each with a single key which itself contains a list. You could do this:
for item in data:
for key, value in item.items():
print value
but a better way would be to change the structure so you only have a single dict:
{
"ice/cold": [
"vanilla",
"hotchoc",
"mango",
"banana"
],
"fire/hot": [
"barbecue",
"hotsalsa",
"sriracha",
"kirikiri"
],
"friendly/mild": [
"ketchup",
"mustard",
"ranch",
"dipster"
]
}
here data is actually a list not a dictionary
and every index of list is a dictionary so just loop through all elements of list and see if it corresponds to desired dictionary
here is the code
data= [
{
"ice/cold": [
"vanilla",
"hotchoc",
"mango",
"banana"
]
},
{
"fire/hot": [
"barbecue",
"hotsalsa",
"sriracha",
"kirikiri"
]
},
{
"friendly/mild": [
"ketchup",
"mustard",
"ranch",
"dipster"
]
}
]
for items in data:
for key, value in items.iteritems():
if key == "ice/cold":
print value

converting mongodb arrays into python arrays

I'm writing a code in which i find this kind of database (i'm using pymongo).
How can i attribute these arrays inside the wishlist field to python arrays?
Alternatively, how can i search my database for a value inside an array inside the wishlist field. E.g.: i want to find all IDs that have, say, ["feldon","c15", "sp"] in their wishlists
{
"_id" : "david",
"password" : "azzzzzaa",
"url" : "url3",
"old_url" : "url3",
"new_url" : ["url1", "url2"],
"wishlist" : [
["all is dust", "mm4", "nm"],
["feldon", "c15", "sp"],
["feldon", "c15", "sp"],
["jenara", "shards", "nm"],
["rafiq", "shards", "nm"]
]
}
You can use distinct if elements in your sublist and are exactly in the same order.
db.collection.distinct("_id", {"wishlist": ["feldon", "c15", "sp"]})
If not, you need to use the aggregate method and the $redact operator.
db.collection.aggregate([
{"$redact": {
"$cond": [
{"$setIsSubset": [
[["feldon","c15", "sp"]],
"$wishlist"
]},
"$$KEEP",
"$$PRUNE"
]
}},
{"$group": {
"_id": None,
"ids": {"$push": "$_id"}
}}
])

Categories