Extract just one value from json array result in vb6 - arrays

The result of json that I received from the SMS sending panel by Rest API is as follows and display in textbox :
{
"status": "OK",
"code": "OK",
"message": "Ok",
"data": {
"messages": [
{
"number": "+9710001529",
"message": "Hello World",
"sender": "+97911308600",
"time": "2022-07-12T20:12:14Z",
"type": "normal"
},
{
"number": "+9710001529",
"message": "Just For Test",
"sender": "+979051931024",
"time": "2022-06-28T23:15:22Z",
"type": "normal"
},
{
"number": "+9710001529",
"message": "Test",
"sender": "+979565547989",
"time": "2022-01-28T16:04:50Z",
"type": "mobilepanel"
},
{
"number": "+9710001529",
"message": "Comment",
"sender": "+979102900089",
"time": "2018-06-16T22:23:23Z",
"type": "normal"
}
]
},
"meta": {
"total": 37,
"pages": 4,
"limit": 10,
"page": 0,
"prev": null,
"next": "http://0.0.0.0:80/v1/inbox?limit=10\u0026page=1"
}
}
Now, I need to fetch the first mobile number with the name "sender" and show it in textbox for searching in database. The result should look like this: +97911308600.
I downloaded VB-JSON, VB6 JSON Parser Class Library and try to get a specific field from JSON data structure. if json result was not array like this code works good:
{
"status": "OK",
"code": "OK",
"message": "Ok",
"data": {
"credit": 2655946.6574392905
}
}
my code :
Dim p As Object
Set p = json.parse(Text1.text)
Debug.Print p.Item("data").Item("credit")
My expected output :
2655946.6574392905
The problem is when the Json result is a collection of arrays. How can I read first "sender" value as Mobile number just like value of "credit"?
Please guide me or post code. Thank you

Short answer:
o.item("data").item("messages").item(1).item("number")
Easy way to find out..
Put a breakpoint right after the .Parse(...) call and then stop your execution and proceed to the "Immediate Window".
Start debugging using the TypeName(...) method from VB6.
?TypeName(o) => Dictionary
?TypeName(o.item("data")) => Dictionary
?TypeName(o.item("data").item("messages")) => Collection
So, this is how the parser renders the array of objects. Instead of a Dictionary, it is a collection. Collections can be indexed via numeric keys (base 1).
Thus,
?TypeName(o.item("data").item("messages").item(1)) => Dictionary
Now, we're back to a Dictionary, so we're back on a JSON object as opposed to an array. You could also have done .Count on the Collection if you needed to iterate.
And, then, finally, extract the field from the collection you wanted:
o.item("data").item("messages").item(1).item("number") => +9710001529
And, you're there.

Try using tiny mdJson.bas module from this thread instead of some bloated components and libraries.
It's a single file JSON parser implementation that uses nested VBA.Collections to represent JSON objects and arrays and uses JSON Path expressions to access nested data.
Your code would become this
Dim p As Object
Set p = JsonParseObject(Text1.text)
Debug.Print JsonValue(p, "data/credit")
You can read the first sender like this
Debug.Print JsonValue(p, "messages/0/sender")
. . . or using JSON Path expressions like this
Debug.Print JsonValue(p, "$.messages[0].sender")

Related

MongoDB Array Query - Single out an array element

I am having trouble with querying a MongoDB collection with an array inside.
Here is the structure of my collection that I am querying. This is one record:
{
"_id": "abc123def4567890",
"profile_id": "abc123def4567890",
"image_count": 2,
"images": [
{
"image_id": "ABC123456789",
"image_url": "images/something.jpg",
"geo_loc": "-0.1234,11.234567890",
"title": "A Title",
"shot_time": "01:23:33",
"shot_date": "11/22/2222",
"shot_type": "scenery",
"conditions": "cloudy",
"iso": 16,
"f": 2.4,
"ss": "1/545",
"focal": 6.0,
"equipment": "",
"instructions": "",
"upload_date": 1234567890,
"update_date": 1234567890
},
{
"image_id": "ABC123456789",
"image_url": "images/something.jpg",
"geo_loc": "-0.1234,11.234567890",
"title": "A Title",
"shot_time": "01:23:33",
"shot_date": "11/22/2222",
"shot_type": "portrait",
"conditions": "cloudy",
"iso": "16",
"f": "2.4",
"ss": "1/545",
"focal": "6.0",
"equipment": "",
"instructions": "",
"upload_date": 1234567890,
"update_date": 1234567890
}
]
}
Forgive the formatting, I didn't know how else to show this.
As you can see, it's a profile with a series of images within an array called 'images' and there are 2 images. Each of the 'images' array items contain an object of attributes for the image (url, title, type, etc).
All I want to do is to return the object element whose attributes match certain criteria:
Select object from images which has shot_type = "scenery"
I tried to make it as simple as possible so i started with:
find( { "images.shot_type": "scenery" } )
This returns the entire record and both the images within. So I tried projection but I could not isolate the single object within the array (in this case object at position 0) and return it.
I think the answer lies with projection but I am unsure.
I have gone through the MongoDB documents for hours now and can't find inspiration. I have read about $elemMatch, $, and the other array operators, nothing seems to allow you to single out an array item based on data within. I have been through this page too https://docs.mongodb.com/manual/tutorial/query-arrays/ Still can't work it out.
Can anyone provide help?
Have I made an error by using '$push' to populate my images field (making it an array) instead of using '$set' which would have made it into an embedded document? Would this have made a difference?
Using aggregation:
db.collection.aggregate({
$project: {
_id: 0,
"result": {
$filter: {
input: "$images",
as: "img",
cond: {
$eq: [
"$$img.shot_type",
"scenery"
]
}
}
}
}
})
Playground
You can use $elemMatch in this way (simplified query):
db.collection.find({
"profile_id": "1",
},
{
"images": {
"$elemMatch": {
"shot_type": 1
}
}
})
You can use two objects into find query. The first will filter all document and will only get those whose profile_id is 1. You can omit this stage and use only { } if you wnat to search into the entire collection.
Then, the other object uses $elemMatch to get only the element whose shot_type is 1.
Check an example here

How to print a json object

Hi Im new to JSON this may be a basic question, im having data as a JSON object and i want to print the "message" data alone. My sample JSON data, in this how can i access message?
{
"name": "Usingtagproject",
"fan_count": 0,
"category": "Product/Service",
"feed": {
"data": [
{
"created_time": "2017-05-02T18:24:27+0000",
"message": "hii",
},
{
"created_time": "2017-05-02T09:26:37+0000",
"message": "Hi Google",
},
{
"created_time": "2017-05-02T09:24:26+0000",
"message": "Hi Demoproject",
}
],
}
JSON is essentially a map (keys with values), that has a specific syntax.
It completely depends on what language you're accessing it in, but you can assume that most languages will have key indexing, so that you can say:
string name = my_json['name']
list<map> data = my_json['data']
for data_map in data:
print "found message: " + data_map['message']

Updating a field with a nested array in Elastic Search

I am trying to update a field in a document with an array. I want to add an array to the field "products". I tried this:
POST /index/type/1/_update
{
"doc" :{
"products": [
{
"name": "A",
"count": 1
},
{
"name": "B",
"count": 2
},
{
"name": "c",
"count": 3
}
]
}
}
this is the error response I am getting when I try and run the code:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "failed to parse [products]"
}
],
"type": "mapper_parsing_exception",
"reason": "failed to parse [products]",
"caused_by": {
"type": "illegal_state_exception",
"reason": "Can't get text on a START_OBJECT at 1:2073"
}
},
"status": 400
}
Anyone know what I am doing wrong?
The message "Can't get text on a START_OBJECT" means that Elasticsearch was expecting an entry of type "string" but you are trying to give an object as input.
If you check Kibana you will find that the field "products" exists there and is defined as a string. But since you are entering a list of dictionaries then the field "products" should have been defined from the beginning as an object (preferably with dynamic fields in it). An example would be (see full example at https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic.html )
"products": {
"dynamic": true,
"properties": {}
}
However since you already have the index then you can't change the mapping so you would need to delete the index, do the mapping beforehand and then do the update.

Getting data from a weird array

I am trying to get som data out of a Facebook array. It has allways worked earlier, but I have problems now for some reason.
$json=json_decode($string,true);
$from= $json['0']['data']['from']['name'];
The array output:
{ "data": [
{
"id": "XXX",
"from": {
"name": "Random name",
"id": "ID123321"
},
And a lot of different parameters and arrays bellow.
What is wrong with my $from variable?
It coud be that there is more than one element in data
Try using $from= $json['0']['data'][0]['from']['name'];

Mapping an array inside an array with a JSON Reader

My JSON looks as follows:
{
"records": [
{
"_id": "5106f97bdcb713b818d7f1f1",
"cn": "lsacco",
"favorites": [
{
"fullName": "Friend One",
"uid": "friend1"
},
{
"fullName": "Friend Two",
"uid": "friend2"
}
]
}
]
}
When I try to use records.favorites as the root for my JSON reader, I do not get any results populated to my model. Is there a way to do this without having to resort to using an association? Note that in my case, records will only have one element despite it showing an array.
records.favorites isn't valid because the property doesn't exist.
You want:
records[0].favorites
records has been declared as an array so records.favorites will point to nothing in the json data file.
using the index in records should solve the problem.

Resources