I have JSON:
{"price" : 12}
and schema:
schema = {
"type" : "object",
"properties" : {
"price" : {"type" : "number"}
},
}
It works to validate the type of value validate({"price" : 12}, schema).
However JSONs like:
{"price_blabla" : 'blabla'}
are also considered valid. How should I change schema so it would check that a JSON contains the particular keys? Basically I have a lot of JSONs and I need to get all that have a certain pattern.
In jsonschema there is property called 'required', using this field
we can check whether a JSON contains the particular keys.
Missing the required field property makes the JSON document invalid.
Sample:
schema = {
"type" : "object",
"properties" : {
"price" : {"type" : "number"}
},"required": ["price"]
}
validate({"price_blabla" : 'blabla'}, schema)
This will throw the following error.
jsonschema.exceptions.ValidationError: 'price' is a required property
Reference :
https://json-schema.org/understanding-json-schema/reference/object.html#required
Related
I must be really slow because I spent a whole day googling and trying to write Python code to simply list the "code" values only so my output will be Service1, Service2, Service2. I have extracted json values before from complex json or dict structure. But now I must have hit a mental block.
This is my json structure.
myjson='''
{
"formatVersion" : "ABC",
"publicationDate" : "2017-10-06",
"offers" : {
"Service1" : {
"code" : "Service1",
"version" : "1a1a1a1a",
"index" : "1c1c1c1c1c1c1"
},
"Service2" : {
"code" : "Service2",
"version" : "2a2a2a2a2",
"index" : "2c2c2c2c2c2"
},
"Service3" : {
"code" : "Service4",
"version" : "3a3a3a3a3a",
"index" : "3c3c3c3c3c3"
}
}
}
'''
#convert above string to json
somejson = json.loads(myjson)
print(somejson["offers"]) # I tried so many variations to no avail.
Or, if you want the "code" stuffs :
>>> [s['code'] for s in somejson['offers'].values()]
['Service1', 'Service2', 'Service4']
somejson["offers"] is a dictionary. It seems you want to print its keys.
In Python 2:
print(somejson["offers"].keys())
In Python 3:
print([x for x in somejson["offers"].keys()])
In Python 3 you must use the list comprehension because in Python 3 keys() is a 'view', not a list.
This should probably do the trick , if you are not certain about the number of Services in the json.
import json
myjson='''
{
"formatVersion" : "ABC",
"publicationDate" : "2017-10-06",
"offers" : {
"Service1" : {
"code" : "Service1",
"version" : "1a1a1a1a",
"index" : "1c1c1c1c1c1c1"
},
"Service2" : {
"code" : "Service2",
"version" : "2a2a2a2a2",
"index" : "2c2c2c2c2c2"
},
"Service3" : {
"code" : "Service4",
"version" : "3a3a3a3a3a",
"index" : "3c3c3c3c3c3"
}
}
}
'''
#convert above string to json
somejson = json.loads(myjson)
#Without knowing the Services:
offers = somejson["offers"]
keys = offers.keys()
for service in keys:
print(somejson["offers"][service]["code"])
I have two collections in the mongo database. At the moment I have an ID document from collection1 in document in collection2. I want to copy some values from Collection1 to nested field (dataFromCollection1) in related documents in Collection2. I'm looking for help because I can not find a solution to pass values from the mongo base fields to variables in python.
Collection1:
{
"_id" : ObjectId("583d498214f89c3f08b10e2d"),
"name" : "Name",
"gender" : "men",
"secondName" : "",
"testData" : [ ],
"numberOf" : NumberInt(0),
"place" : "",
"surname" : "Surname",
"field1" : "eggs",
"field2" : "hamm",
"field3" : "foo",
"field4" : "bar"
}
Collection2:
{
"_id" : ObjectId("58b028e26900ed21d5153a36"),
"collection1" : ObjectId("583d498214f89c3f08b10e2d")
"fieldCol2_1" : "123",
"fieldCol2_2" : "332",
"fieldCol2_3" : "133",
"dataFromCollection1" : {
"name" : " ",
"surname" : " ",
"field1" : " ",
"field2" : " ",
"field3" : " ",
"field4" : " "
}
}
I think you should use aggregate function in pymongo package, in aggregate you can use $lookup to match the key value pairs and project for projecting the required fields this question has already been asked so this pymongo - how to match on lookup? might helps you.
Then you can use the $out function in aggregate to create the new updated collection of your interest or you can also update the existing collection by using the update in pymongo.
Is there a way to select only userId field from _id embedded document?
I tried with below query
And also i wants to delete all the documents that comes as output to the below query may be in a batch of 10000 per batch by keeping database load and this operation should not hamper the database. please suggest.
Sample Data:
"_id" : {
"Path" : 0,
"TriggerName" : "T1",
"userId" : NumberLong(231),
"Date" : "02/09/2017",
"OfferType" : "NOOFFER"
},
"OfferCount" : NumberLong(0),
"OfferName" : "NoOffer",
"trgtm" : NumberLong("1486623660308"),
"trgtype" : "PREDEFINED",
"desktopTop-normal" : NumberLong(1)
query:
mongo --eval 'db.l.find({"_id.Date": {"$lt" : "03/09/2017"}},{"_id.userId":1}).limit(1).forEach(printjson)
output:
{
"_id" : {
"Path" : 0,
"TriggerName" : "T1",
"userId" : NumberLong(231),
"Date" : "02/09/2017",
"OfferType" : "NOOFFER"
}
I'm trying out json since I have to work with Cisco API and I can't figure out how to loop through the json object.I can get my keys but i can't get the values.
I am using http://www.jsoneditoronline.org/ to me understand json format but this is what I have so far..
json file :
{
"queryResponse" : {
"#rootUrl" : "\/webacs\/data",
"#requestUrl" : "https : \/\/192.168.116.207\/webacs\/api\/v1\/data\/DeviceGroups\/42",
"#responseType" : "getEntity",
"entity" : {
"#url" : "\/webacs\/data\/className\/15",
"#type" : "className",
"#dtoType" : "deviceGroupsDTO_$$_javassist_5196",
"deviceGroupsDTO" : {
"#id" : "15",
"#displayName" : "String value",
"clearedAlarms" : 1,
"criticalAlarms" : 1,
"groupId" : 2,
"groupName" : "String value",
"informationAlarms" : 1,
"majorAlarms" : 1,
"minorAlarms" : 1,
"name" : "String value",
"warningAlarms" : 1
}
}
}
}
My python script :
import json
jsondata = json.load(open('data.json'))
for rows in jsondata['queryResponse']['entity']['deviceGroupsDTO']:
print(rows)
it print's :
name
#id
warningAlarms
#displayName
informationAlarms
clearedAlarms
majorAlarms
groupId
groupName
criticalAlarms
minorAlarms
not sure what i'm doing wrong...
jsondata['queryResponse']['entity']['deviceGroupsDTO'] is a dictionary.
Iterate over items() to get key, value pairs:
for key, value in jsondata['queryResponse']['entity']['deviceGroupsDTO'].items():
print(key, value)
Note that, in case of python2, you would better use iteritems() in place of items().
See also: What is the difference between dict.items() and dict.iteritems()?
Data:
{
"_id" : ObjectId("50cda9741d41c81da6000002"),
"template_name" : "common_MH",
"role" : "MH",
"options" : [
{
"sections" : [
{
"tpl_option_name" : "test321",
"tpl_option_type" : "string",
"tpl_default_value" : "test321"
}
],
"tpl_section_name" : "Test"
}
]
}
could I modify tpl_default_value in options.$.section.$.tpl_option_name = 'test321'?
I already try too times, but I can't solve.
please assist me, thanks.
This is a bad schema for doing these kinda of updates, there is a JIRA for multi-level positional operator however it is not yet done: https://jira.mongodb.org/browse/SERVER-831
Ideally you either have to update this client side and then atomically set that section of the array:
$section = {
"tpl_option_name" : "test321",
"tpl_option_type" : "string",
"tpl_default_value" : "test321"
};
db.col.update({}, {$set: {options.$.sections.1: $section}})
Or you need to change your schema. Does the sections really need to be embedded? I noticed that you have a tpl_section_name in the top level but then you are nesting sections within that, it sounds more logical that only one section should be there.
That document would be easier to update.