This question already has answers here:
Parsing json and searching through it
(5 answers)
Closed 5 years ago.
I have the following JSON string and I want to obtain doc_count:
import json
text = '''{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 11,
"max_score": 0,
"hits": []
},
"aggregations": {
"range": {
"buckets": [
{
"key": "2017-02-17T15:00:00.000Z-2017-02-17T16:00:00.000Z",
"from": 1487343600000,
"from_as_string": "2017-02-17T15:00:00.000Z",
"to": 1487347200000,
"to_as_string": "2017-02-17T16:00:00.000Z",
"doc_count": 2
}
]
}
}
}'''
obj = json.loads(text)
obj
I tried obj['aggregations']['range']['buckets']['doc_count'], but it does not work. How can I search through the hierarchy of this JSON file?
Because 'buckets' key contains array of element. You needs
obj['aggregations']['range']['buckets'][0]['doc_count']
You're missing the fact that the "buckets" key contains a list. You need:
obj['aggregations']['range']['buckets'][0]['doc_count']
Note the [0] after selecting the buckets key.
Related
This question already has answers here:
Filter dict to contain only certain keys?
(22 answers)
Closed 2 years ago.
I have my dict as follows
user_model = {
"users": [{
"userid": 100,
"level": 1,
"score": 5,
},
{
"userid": 101,
"level": 2,
"score": 5,
},
{
"userid": 100,
"level": 2,
"score": 5,
},
{
"userid": 103,
"level": 1,
"score": 2,
}
]
}
Can someone please point me in right direction to update only "score" if my "userid" is 103 and "level" is 2.
Thanks
This way you can list all the data in your json:
for item in user_model['users']:
print(item) #check items
if item['userid'] == 103:
item['score'] = 25
print(item)
I found a question which is technically the same but doesn't answer my question fully and was asked 7 years ago.
The problem which I can't solve is updating a dictionary in array in document. I needed to change deck to True, but it doesn't update it. Also I didn't get any errors.
Document Structure
{
"user": 1234,
"money": 0
"inv_max": 100,
"cards": [
{
"name": "somename",
"power": 11,
"health": 10,
"rarity": 'bronze'
"deck": False,
}
],
"packs": {
"bronze": 0,
"silver": 0,
"gold": 0,
"diamond": 0,
"mythical": 0
}
}
Code which should update it (which I used)
await db.inventory.update_one(
{"user": self.user_id},
{"$set": {f"cards.{index}.deck": True}}
)
In case it's needed, I use MongoDB Atlas.
Use the positional operator $ to update:
db.inventory.updateOne(
{ "user": "1234", "cards.name": "somename"},
{ "$set": { "cards.$.deck" : "True" }} )
If you know the index you can do something like this
db.inventory.update_one(
{"user": self.user_id},
{$set: {"cards.0.deck":true}}
)
As part of a Python program, I want to merge JSON objects that contain identically structured data. For instance:
{
"responseStatus": "SUCCESS",
"responseDetails": {
"total": 5754,
},
"data": [
{
"id": 1324651
},
{
"id": 5686131
}
]
}
What I want to do is to add the content of the data array of my section object into the data array of my first object.
So, assuming:
thejson1 = json.loads({"responseStatus": "SUCCESS","responseDetails": {"total": 5754,},"data": [{"id": 1324651},{"id": 5686131}]})
thejson2 = json.loads({"responseStatus": "SUCCESS","responseDetails": {"total": 1234,},"data": [{"id": 2165735},{"id": 2133256}]})
I thought that executing:
thejson1["data"].append(thejson2["data"])
Would expand thejson1 into:
{
"responseStatus": "SUCCESS",
"responseDetails": {
"total": 5754,
},
"data": [
{
"id": 1324651
},
{
"id": 5686131
},
{
"id": 2165735
},
{
"id": 2133256
}
]
}
But what it does instead is add thejson2 data as an array within the data array of thejson1:
{
"responseStatus": "SUCCESS",
"responseDetails": {
"total": 5754,
},
"data": [
{
"id": 1324651
},
{
"id": 5686131
},
[
{
"id": 2165735
},
{
"id": 2133256
}
]
]
}
So, what am I doing wrong? It looks like append adds the data array of the second JSON object instead of its content, but note that I can't know in advance the contents of the "data" array in my JSON input, so I can't write code that specifically loops in the "id" objects to add them one by one.
Thanks in advance!
R.
You're looking for extend, not append.
thejson1["data"].extend(thejson2["data"])
append takes the single argument and insert it to the end. While extend extends the list by adding all the individual values in the argument list to the end.
# example:
a=[1, 2, 3]
b = a[:].append([4, 5])
# b = [1, 2, 3, [4, 5]]
c = a[:].extend([4, 5])
# c = [1, 2, 3, 4, 5]
thejson1 = {"responseStatus": "SUCCESS","responseDetails": {"total": 5754,},"data": [{"id": 1324651},{"id": 5686131}]}
thejson2 = {"responseStatus": "SUCCESS","responseDetails": {"total": 1234,},"data": [{"id": 2165735},{"id": 2133256}]}
thejson1["data"] += thejson2["data"]
Output:
{'responseDetails': {'total': 5754}, 'data': [{'id': 1324651}, {'id': 5686131}, {'id': 2165735}, {'id': 2133256}], 'responseStatus': 'SUCCESS'}
You can also use += to extend.
For example, I would like to aggregate by state, but the following returns data tyep is string not an array .
How can I write an Elasticsearch terms aggregation that return an array ?
part of my code:
import urllib2 as urllib
import json
query = {
"size":0,
"aggs":{
"states":{
"terms":{
"field":"states.raw",
"size":8
}
}
}
}
query = json.dumps(query )
headers = {'Content-type': 'application/json'}
req = urllib2.Request(url, query , headers)
out = urllib2.urlopen(req)
rs = out.read()
print type(rs )
return :
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0,
"hits": []
},
"aggregations": {
"states": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "New York",
"doc_count": 200
},
{
"key": "California",
"doc_count": 10
},
{
"key": "New Jersey",
"doc_count": 10
},
{
"key": "North Carolina",
"doc_count": 1802
},
{
"key": "North Dakota",
"doc_count": 125
}
]
}
}
}
I try to get return data by rs['aggregations']['states']['buckets'][0]['key']
but get the error msg
"TypeError: string indices must be integers, not str"
I found the return data type is string ,how to make the return data is an array ?
Run
import json
...
rs = json.loads(rs)
Then rs will become an object that you access using s['aggregations']['states']['buckets'][0]['key']
However, it's recommended that you use the python client for elasticsearch instead of writing your own, as the latter already handles what you are looking for among other things. Check my answer here for an example on how to run a query using elasticsearch-py.
Here's the link for elasticsearch-py's documentation:
https://elasticsearch-py.readthedocs.io/en/master/
I'm trying to dynamically add some data to a dictionary in python which I then convert to a json formatted string.
{
"Module": "lights",
{
"id": 1,
"power": 50
},
{
"id": 2,
"power": 0
},
{
"id": 3,
"power": 25
}
}
the id and power need to be added dynamically how would I achieve this with python? How would I read the same json format as well?
that's an invalid construct in both JSON and Python
it should be something like
{
"Module": "lights",
"Values":[
{
"id": 1,
"power": 50
},
{
"id": 2,
"power": 0
},
{
"id": 3,
"power": 25
}
]
}
grouping all the dicts {_id: ..., power: ...} in a list
taken care of that, converting from JSON to dict and vice-versa one could use the load/loads and dump/dumps methods from the json or simplejson packages