Edit embedded document in mongodb using python(pymongo) - python

I am getting following error while updating a document inside a collection in mongodb using python using pymongo. Any help is greatly appreciated.
x = 4
str = "ratings.${x}.rating"
db.amitava1.update({"_id":1},{"$inc":{[str]:1 } } )
Traceback (most recent call last):
File "", line 1, in TypeError: unhashable type:
'list'***

Youre getting that error because you're doing {"$inc":{[str]:1 }}. Namely, trying to assing [str] as the key in the in the dictionary {[str]:1 }.
It says that because you cannot use a list as a key for a dictionary, because a list is unhashable. You can only use hashable types (types that have a __hash__ function defined) key values.
It looks like you have some other issues with your code though. I think you need to use
str = "ratings.${x}.rating".format(x=x)
or something in order to replace the x in your string.

Related

Conversion of string to dictionary

I have captured a string from a REST get request and have placed it in a variable. The string is:
{"name":"na1mailboxarchive","objectCount":49564710,"dataBytes":36253526882451},{"name":"na1mailboxarchive2","objectCount":17616567,"dataBytes":13409204616615}
I am trying to convert it to a dictionary so I can increment through it and capture the bucket name, size and object count. I have tried eval()
bucket_dict = eval(bucket_info)
but the program errors out with a:
Traceback (most recent call last):
File "./test.py", line 83, in <module>
for k,b in bucket_dict.items():
AttributeError: 'tuple' object has no attribute 'items'
When I print the value of bucket_dict I get:
({'name': 'na1mailboxarchive', 'objectCount': 49564710, 'dataBytes': 36253526882451}, {'name': 'na1mailboxarchive2', 'objectCount': 17616567, 'dataBytes': 13409204616615})
I think the foul up is the () at the beginning and the end of the dictionary. Nothing else I have tried works either.
Try this instead
import ast
string = '{"name":"na1mailboxarchive","objectCount":49564710,"dataBytes":36253526882451},{"name":"na1mailboxarchive2","objectCount":17616567,"dataBytes":13409204616615}'
result = ast.literal_eval(string)
print(result)
result is returned as a dictionary
I got it figured out.
Firstly the json return from the REST API get is badly formatted. I will take that up with the vendor. Secondly I used some iof the infrmation form #PrashantKumar and #MisterMiyagi to sus out the issue I was having. In my original code I had loaded the list with:
bucket_info = [acct_string[acct_string_start+11:acct_len-4]]
The variable was capturing the leading "[" and trailing "]" as a part of the string. Once I removed them then the list behaved correctly and I now can work with it. Thank you for the information and the trail markers.

Using Find in pymongo

I want to use .find() like this for mongoDB in Python :
import pymongo
client = pymongo.MongoClient('mongodb://localhost:27000')
db = client['responsi']
cursor = db['produk']
for x in cursor.find({"pricing.pct_savings":{"$gt":25}}).sort({"pricing.pct_savings":-1}):
print(x)
But, it showing error like this :
Traceback (most recent call last):
File "Find.py", line 7, in <module>
for x in cursor.find({"pricing.pct_savings":{"$gt":25}}).sort({"pricing.pct_savings":-1}):
File "G:\PROGRAM FILES\Python\lib\site-packages\pymongo\cursor.py", line 708, in sort
keys = helpers._index_list(key_or_list, direction)
File "G:\PROGRAM FILES\Python\lib\site-packages\pymongo\helpers.py", line 69, in _index_list
raise TypeError("if no direction is specified, "
TypeError: if no direction is specified, key_or_list must be an instance of list
How to solved this problem?
Thank you!
Sorry, I have bad score in english.
As opposed to the mongo shell, pymongo takes key and direction as the arguments to the sort method (or list, but that's another form that is not relevant to you currently, I'll show it too)
So your query should actually be cursor.find({"pricing.pct_savings":{"$gt":25}}).sort("pricing.pct_savings", pymongo.DESCENDING)
The other form gets a list of tuples of field name and the direction, and allows you to sort by multiple fields, for example collection.find().sort([('my_field_1',pymongo.DESCENDING), ('my_field_2',pymongo.ASCENDING)])
See the relevant documentation here https://api.mongodb.com/python/current/api/pymongo/cursor.html?highlight=sort#pymongo.cursor.Cursor.sort
You can find the ASCENDING and DESCENDING constants here https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.ASCENDING
BTW (not related to your original question)
db['produk'] is actually a collection, not a cursor, so it would be better if you would call it collection, and not cursor.
Cursor is what find() returns
should only have this structure
from bson import ObjectId
id = '375g68h97b680jf78j'
data = cursor.find_one_and_delete({'_id': ObjectId(id)})

TypeError: string indices must be integers, not str // Trying to get value of key

I'm trying to get a key from a value that I am returned with, but when i use the easy approach to just get the value of a specific key I get the error: TypeError: string indices must be integers, not str
I also tried .get() method, but it did not work either. Could someone please point me out what I am doing wrong?
>>> import urllib2
>>> url = 'http://192.168.250.1/ajax.app?SessionId=8ef05397-ef00-451a-bc1c-c0d61
5a4811d&service=getDp&plantItemId=1413'
>>> response = urllib2.urlopen(url)
>>> dict = response.read()
>>> dict
'{"service":"getDp","plantItemId":"1413","value":" 21.4","unit":"\xc2\xb0C"}'
>>> dict['value']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string indices must be integers, not str
Looks like 'dict' is a variable of type string, not a dictionary. You should parse the string into a suitable dictionary format (like JSON). Here's a code that will resolve that issue:
import json
json_string = response.read()
dict = json.loads(json_string)
Now, for dict['value'] you will get what you need.
response.read() is returning an object of type string and not a dictionary and you can index a string using only integer indices and hence you are getting your error.
You need to parse this string and convert it to a dictionary. To convert a string of a dictionary back to a dictionary you can do this:
import ast
dict = ast.literal_eval(dict)
print dict['value']
Tried it on my machine with Python 2.7 and it works.

'string indices must be integers' error with this JSON dict

I have a dictionary with a single item in it created using json.loads(). The data structure looks like this:
{"teamId":96}
When I attempt to access the dictionary value by using the following:
mydict = mydict[u'teamId']
I get the following error:
Traceback (most recent call last):
File "C:\Python27\counter.py", line 65, in <module>
print home_team[u'teamId']
TypeError: string indices must be integers
Can anyone explain to me what the issue is here? The code looks like it should work to me.
Thanks
You need json.dumps(you_file) :
json.loads(json.dumps(your_file))

NLTK python error: "TypeError: 'dict_keys' object is not subscriptable"

I am following instructions for a class homework assignment and I am supposed to look up the top 200 most frequently used words in a text file.
Here's the last part of the code:
fdist1 = FreqDist(NSmyText)
vocab=fdist1.keys()
vocab[:200]
But when I press enter after the vocab 200 line, it returns:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'dict_keys' object is not subscriptable
Any suggestions on how to fix this so it can correctly return an answer?
Looks like you are using Python 3. In Python 3 dict.keys() returns an iterable but not indexable object. The most simple (but not so efficient) solution would be:
vocab = list(fdist1.keys())[:200]
In some situations it is desirable to continue working with an iterator object instead of a list. This can be done with itertools.islice():
import itertools
vocab_iterator = itertools.islice(fdist1.keys(), 200)
I am using python 3.5 and I meet the same problem of TypeError.
Using vocab = list(fdist1.keys()) does not give me the top 50 most frequently used words.
But fdist1.most_common(50) does.
Further,if you just want to show those top 50 words not with their frequency,you can try :
[word for (word, freq) in fdist1.most_common(50)]
If you want to get elements as keys and values (word and frequency), you can use:
list(fdist1.items())[:200]
To print the most frequently used 200 words use:
fdist1.most_common(200)
The above line of code will return the 200 most frequently used words as key-frequency pair.
If your using python 3 try:
fdist1.most_common(200)
instead, to get the 200 most frequent words.
fdist1 = FreqDist(NSmyText)
vocab=fdist1.keys()
This code is using in Python2.7.
So you should do some change.
dic.keys() returns an iteratable. So using:
list(fdist1.keys())

Categories