{
"_id":"1",
"company":"ABCD",
"Address":{
"Location":"XYZ"
},
"empName":[{
"ID":1,
"Name":"test1"
},
"ID":2,
"Name":"test2"
},
"ID":3,
"Name":"test3"
}]
}
am using mongoTemplate query,
Criteria findCriteria1 = Criteria.where("_id").is("1");
Criteria find2Criteria = Criteria.where("empName").elemMatch(Criteria.where("ID").is(1));
BasicQuery basicQuery = new BasicQuery(findCriteria1.getCriteriaObject(), find2Criteria.getCriteriaObject());
mongoTemplate.findOne(basicQuery, ClassName.class);
but my result as below with other fields displayed null.
{
"_id":"1",
"company":null,
"Address":null,
"empName":[{
"ID":1,
"Name":"test1"
}]
}
my expected result should be like this,
"_id":"1",
"company":"ABCD",
"Address":{
"Location":"XYZ"
},
"empName":[{
"ID":1,
"Name":"test1"
}]
Can you please help me to fix this issue.
Thanks in advance,
You can use below code.
You can chain the fields you require in the Field class.
Criteria criteria = Criteria.where("_id").is("1");
Query query = new Query(criteria);
query.fields().elemMatch("empName", Criteria.where("ID").is(1)).include("company");
mongoTemplate.findOne(query , ClassName.class);
Do Read the documentation for Criteria and BasicQuery.
The second argument in this
BasicQuery basicQuery = new BasicQuery(findCriteria1.getCriteriaObject(), find2Criteria.getCriteriaObject());
is basically a projection. i.e. you are telling the driver to fetch only the fields mentioned in those. Hence other fields are not fetched and hence null.
If you want to fetch all fields this is what you should do in your case
Criteria findCriteria1 = Criteria.where("_id").is("1");
Criteria find2Criteria = Criteria.where("empName").elemMatch(Criteria.where("ID").is(1));
BasicQuery basicQuery = new BasicQuery(findCriteria1.andOperator(find2Criteria).getCriteriaObject());
Related
I have a json as below:
[
{
"id":6619137,
"oid":"6fykq37gm60x",
"key":{
"key":"6619137"
},
"name":"Prod",
"planKey":{
"key":"PDP"
},
"environments":[
{
"id":6225923,
"key":{
"key":"6619137-6225923"
},
"name":"Production",
"deploymentProjectId":6619137,
}
],
},
{
"id":6619138,
"oid":"6fykq37gm60y",
"key":{
"key":"6619138"
},
"name":"QA",
"planKey":{
"key":"QDP"
},
"environments":[
{
"id":6225924,
"key":{
"key":"6619138-6225924"
},
"name":"QA",
"deploymentProjectId":6619138,
}
],
},
]
I can use the below code to extract the value of id and environments.id based on the name value. projectID will give 6619137 and environmentID will give 6225923
def e = json.planKey.find{it.name=='Prod'}
def projectID = e.id
def environmentID = e.environments[0].id
However, when I try to extract the value of id and environments.id based on the plankey.key value (e.g. PDP or QDP), using the same format above returns me an error of java.lang.NullPointerException: Cannot get property 'id' on null object at Script60.run(Script60.groovy:52)
def e = json.planKey.find{it.planKey=='{key=PDP}'}
def projectID = e.id
def environmentID = e.environments[0].id
Is there a way I can get the projectID with the plankey key value?
Think of your JSON object as a key/value map with multiple levels. There is no such item as
json.find{it.planKey=='{key=PDP}'}
However, you can find with values at any level, like this:
def e = json.find{it.planKey.key == "PDP"}
If you have a structure where planKey may not exist, or it doesn't always have key, that's a bit different, but from your question it sounds like that's not the case here.
EDIT: correcting syntax based on comment below.
I just discovered glom and the tutorial makes sense, but I can't figure out the right spec to use for chrome BrowserHistory.json entries to create a data structure grouped by client_id or if this is even the right use of glom. I think I can accomplish this using other methods by looping over the json, but was hoping to learn more about glom and its capabilities.
The json has Browser_History with a list for each history entry as follows:
{
"Browser_History": [
{
"favicon_url": "https://www.google.com/favicon.ico",
"page_transition": "LINK",
"title": "Google Takeout",
"url": "https://takeout.google.com",
"client_id": "abcd1234",
"time_usec": 1424794867875291
},
...
I'd like a data structure where everything is grouped by the client_id, like with the client_id as the key to a list of dicts, something like:
{ 'client_ids' : {
'abcd1234' : [ {
"title" : "Google Takeout",
"url" : "https://takeout.google.com",
...
},
...
],
'wxyz9876' : [ {
"title" : "Google",
"url" : "https://www.google.com",
...
},
...
}
}
Is this something glom is suited for? I've been playing around with it and reading, but I can't seem to get the spec correct to accomplish what I need. Best I've got without error is:
with open(history_json) as f:
history_list = json.load(f)['Browser_History']
spec = {
'client_ids' : ['client_id']
}
pprint(glom(data, spec))
which gets me a list of all the client_ids, but I can't figure out how to group them together as keys rather than have them as a big list. any help would be appreciated, thanks!
This should do the trick although I'm not sure if this is the most "glom"-ic way to achieve this.
import glom
grouping_key = "client_ids"
def group_combine (existing,incoming):
# existing is a dictionary used for accumulating the data
# incoming is each item in the list (your input)
if incoming[grouping_key] not in existing:
existing[incoming[grouping_key]] = []
if grouping_key in incoming:
existing[incoming[grouping_key]].append(incoming)
return existing
data ={ 'Browser_History': [{}] } # your data structure
fold_spec = glom.Fold(glom.T,init = dict, op = group_combine )
results = glom.glom(data["Browser_History"] ,{ grouping_key:fold_spec })
Trying to pull first value from a parsed JSON string using the JsonConverter library.
What I currently have is:
result = objHTTP.responseText
Set parsedResult = JsonConverter.ParseJson(result)
i = 3
For Each Item In parsedResult("From")
wsSheet0.Cells(i, 12) = parsedResult("From")(Item)("Price")
i = i + 1
Next
With parsedResult("From")
wsSheet0.Cells(11, 12) = parsedResult("From")("Chocolate")("Price")("AsAtDate")
End With
The last line of this gets a type mismatch error, so I'm still trying to figure out how to just pull that one line item.
For the sake of clarity, the parsed JSON string looks like:
{
"From":{
"Chocolate":{
"Price":1.0,
"AsAtDate":"2018-05-04T00:00:00"
},
"Lime":{
"Price":1.35415115,
"AsAtDate":"2018-05-04T00:00:00"
},
"Strawberry":{
"Price":1.19517151,
"AsAtDate":"2018-05-04T00:00:00"
},
"Vanilla":{
"Price":0.77522986,
"AsAtDate":"2018-05-04T00:00:00"
},
"Blueberry":{
"Price":1.00084071,
"AsAtDate":"2018-05-04T00:00:00"
},
"Lemon":{
"Price":0.75030012,
"AsAtDate":"2018-05-04T00:00:00"
}
},
"To":"Chocolate",
"RequestedDate":"2018-05-22T08:26:16"
}
Use
parsedResult("From")("Chocolate")("AsAtDate")
Or more generally to get all:
parsedResult("From")(item)("AsAtDate")
What is the most dynamic way of checking each instance of a json response value matches another json response value within a script assertion?
What I mean is lets say I have the following response below:
{
"xxx": [{
"roomInformation": [{
"xxx": xxx
}],
"totalPrice": xxx
},
{
"roomInformation": [{
xxx: xxx
}],
"totalPrice": xxx
}
]
}
I want to check that the first room price to match with the first totalPrice and the second roomPrice to match with the second totalPrice. It has to be dynamic as I may get many different instances of this so I can't simply just look through the json with [0] and [1]. Virtually check each roomPrice matches with its corresponding totalPrice.
Thanks
So given the Json as a variable:
def jsonTxt = '''{
"hotels": [{
"roomInformation": [{
"roomPrice": 618.4
}],
"totalPrice": 618.4
},
{
"roomInformation": [{
"roomPrice": 679.79
}],
"totalPrice": 679.79
}
]
}'''
We can then use the following script:
import groovy.json.*
new JsonSlurper().parseText(jsonTxt).hotels.each { hotel ->
assert hotel.roomInformation.roomPrice.sum() == hotel.totalPrice
}
As you can see, I'm using sum to add all the roomInformation.roomPrice values together. In your example, you only have one price, so this will be fine.. And it will also cover the case where you have multiple rooms adding up to make the total
Here is the script assertion to check each roomPrice is matching or not with totalPrice.
EDIT: based on OP's full response provided here
Script Assertion:
//Check if the response is not empty
assert context.response, "Response is empty or null"
def json = new groovy.json.JsonSlurper().parseText(context.response)
def sb = new StringBuffer()
json.regions.each { region ->
region.hotels.each { hotel ->
(hotel?.totalPrice == hotel?.roomInformation[0]?.roomPrice) ?: sb.append("Room price ${hotel?.roomInformation[0]?.roomPrice} is not matching with total price ${hotel.totalPrice}")
}
}
if (sb.toString()) {
throw new Error(sb.toString())
} else { log.info 'Prices match' }
Just confused with one little thing.
I am currently getting { "data": [ { "response": "true" } ] } with the following code.
But I simple want to get { "response": "true" }.
I tried every way I can but I kept failing.
I will appreciate a lot if you can help me with it.
Set Dataset = JSON.parse("{ ""data"": [] }")
Set Record = JSON.parse("{}")
Record.set "response", "true"
Dataset.data.push(Record)
Set Record = nothing
Data = JSON.stringify(Dataset, null, 2)
Set Record = JSON.parse("{}")
Record.set "response", "true"
Data = JSON.stringify(Record, null, 2)
I assume that JSONObject.data.push adds the record to an unnamed array.