I want to access element from a json which is the response from one query.
The json structure is :
json = { "result": {
"12CUDzb3oe8RBQ4tYGqsuPsCbsVE4KWfktXRihXf8Ggq": [
20964,
347474,
347475
],
"12ashmTiFStQ8RGUpi1BTCinJakVyDKWjRL6SWhnbxbT": [
1992,
1993,
109096
],
}}
I want to get the 1st element(result[0]) key from result object ie 12CUDzb3oe8RBQ4tYGqsuPsCbsVE4KWfktXRihXf8Ggq in some variable a and the corresponding array ie [20964, 347474,347475 ] in some varible b.
The problem I am having is that 1st element key value in this case "12CUDzb3oe8RBQ4tYGqsuPsCbsVE4KWfktXRihXf8Ggq" always changes for every query!
Can someone show me the way how can I access it correctly?
json.begin() will give you an iterator pointing to the first element. Then you can access its' key and value using:
auto key = json.begin().key();
auto value = json.begin().value();
Related
The following text is a bit of std::string text that is generated by another app (I do not have control of what the app sends me). I have tried for days to get this converted into a QJsonArray and cannot figure this out. I am using C++ within QT. Does anyone have a bit of direction or sample C++ code that could solve this?
{
"saved_mik_yous": {
"2120ce2d-a5b1-49b8-8384-3781b7b2d73b": {
"name": null,
"id": "2120ce2d-a5b1-49b8-8384-3781b7b2d73b",
"start": 1565288936.1127193,
"end": 1565289128.1236603,
"mixxer": 128.567505,
"mik_source": "algo"
},
"bf855c0d-a71d-42ea-b3ef-7cbe0e2c7a3d": {
"name": null,
"id": "bf855c0d-a71d-42ea-b3ef-7cbe0e2c7a3d",
"start": 1565301673.4609745,
"end": 1565301832.665656,
"mixxer": 308.485107,
"mik_source": "algo"
}
},
"mik_you_state": "completed"
}
All you have to do is this:
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(str));
Then, you can access the values for the keys for example as:
doc["saved_mik_yous"]
And so on.
Mind you, the json you are showing seems to be an object rather than an array since it contains key-value pairs rather than a list of elements inside square brackets. So, whilst it does not matter when you are converting the std::string into a QJsonDocument, you need to access the values by keys rather than indices.
If you are getting dynamic json which can be either an array or object, you can always check for the type with isArray() or isObject() to convert it to the right type.
So i want to create a simple Dynamodb table called reminders which at the moment has 3 columns :
reminder_id : This is the hash key
reminder_tag: I want to have a global secondary index on this field . But at the same time i want to ensure that the tags attribute should have the datatype of Set . Because there can be multiple tags on a reminder.
reminder_title: I also want to have a global secondary index on this field. This will be a string field.
I checked the documentation : https://boto3.amazonaws.com/v1/documentation/api/latest/reference/customizations/dynamodb.html#valid-dynamodb-types on what are the possible datatypes available in Boto3 .
So i have come up with this script :
import boto3
def create_reminders_table():
"""Just create the reminders table."""
session = boto3.session.Session(profile_name='dynamo_local')
dynamodb = session.resource('dynamodb', endpoint_url="http://localhost:8000")
table = dynamodb.create_table(
TableName='Reminders',
KeySchema=[
{
'AttributeName': 'reminder_id',
'KeyType': 'HASH'
}
],
AttributeDefinitions=[
{
'AttributeName': 'reminder_id',
'AttributeType': 'S'
},
{
'AttributeName': 'reminder_tag',
'AttributeType': 'SS'
},
{
'AttributeName': 'reminder_title',
'AttributeType': 'S'
}
],
GlobalSecondaryIndexes=[
{
'IndexName': 'ReminderTagGsi',
'KeySchema': [
{
'AttributeName': 'reminder_tag',
'KeyType': 'HASH'
}
],
'Projection': {
'ProjectionType': 'INCLUDE',
'NonKeyAttributes': [
'reminder_title'
]
}
},
{
'IndexName': 'ReminderTitleGsi',
'KeySchema': [
{
'AttributeName': 'reminder_title',
'KeyType': 'HASH'
}
],
'Projection': {
'ProjectionType': 'KEYS_ONLY'
}
}
],
BillingMode='PAY_PER_REQUEST'
)
return table
if __name__ == '__main__':
movie_table = create_reminders_table()
print("Table status:", movie_table.table_status)
But when i run this i get the below issue:
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the CreateTable operation: Member must satisfy enum value set: [B, N, S]
I searched and came across this question asked by someone which has the same issue : https://forums.aws.amazon.com/thread.jspa?messageID=613970
Can someone please help me with this since the solution of not providing a datatype either does not work .
Also is it possible to have an index on a an attribute which is of value Set ? I mean i should enable the user to search for reminders with a tag , and for doing that i need to have a set.
Request someone to please help me regarding this.
Is it possible to have an index on an attribute which is of value Set ?
No. As the CreateTable docs say, "the attributes in KeySchema must also be defined in the AttributeDefinitions", to a data type to one of (S)tring, (N)umber or (B)inary."
enable the user to search for reminders with a tag , and for doing that i need to have a set.
A DynamoDB workaround for one-many relations is a composite sort key as in urgent#work. That would only be sensible for a small, fixed number of tags, though.
Your least-bad option is to query by user (and perhaps further narrowing with some sort key), then filtering the results by tag membership outside DynamoDB. (N.B. The IN operator cannot be used in a Query's FilterConditionExpression, so it's of no use to you here).
I want to have a global secondary index on reminder_title
reminder_title is a poor candidate for an index Primary Key. An index's (and table's) Primary Key must ensure per-record uniqueness. A title would likely not. You probably need a combination of 3 elements, user_id, request_id and title, to ensure key uniqueness across records.
Consider a composite Primery Key with, say, user_id for the Partition Key (= HASH) and a compound sort key in a new column (SK) that concatenates title#request_id. You would then search by-user-by-title with:
user_id="Zaphod" AND begins_with(SK, "exercise")
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html
“Each primary key attribute must be a scalar (meaning that it can hold only a single value). The only data types allowed for primary key attributes are string, number, or binary. There are no such restrictions for other, non-key attributes.”
I wonder if it's possible to create an index that could look like this
{
"dispenserId": "my-dispenser-123", // primary key
"users": ["user5", "user12"],
"robotId": "my-robot-1",
"enabled": true,
"side": left
}
Based on my DynamoDB documents that look like this
{
"robotId": "my-robot-1", // primary key
"dispensers": {
"left": "left-dispenser-123",
"right": "right-dispenser-123",
"users": ["user5", "user12"]
},
"enabled": true,
"users": ["user1", "user32"]
}
I can't figure out how to point at either dispensers.left or dispensers.right and use that as a key, neither can I figure out how to make a side: left/right attribute based on the path of the dispenser ID.
Can it be achieved with the current structure? If not, what document structure would you guys suggest instead. which allows me to hold the same data?
What you are trying to do (use a map element as a key attribute for an index) is not supported by DynamoDB.
The index partition key and sort key (if present) can be any base table attributes of type string, number, or binary. (Source)
You cannot use (an element of) a map attribute as a a key attribute for an index because the key attribute must be a string, number, or binary attribute from the base table.
Consider using the adjacency list design pattern for your data. It will allow you to easily add both the left and right dispensers to your index.
My new structure looks like this
partition key: robotId
sort key: compoundKey
[
{
"robotId": "robot1",
"enabled": true,
"users": [
"user1",
"user3"
],
"compositeKey": "robot--robot1"
},
{
"robotId": "robot1",
"dispenserId": "dispenser1",
"compositeKey": "dispenser--dispenser1",
"side": "left",
"users": [
"user4",
"user61"
]
}
]
Then I have an index with the dispenserId as partition key, so I can either look the dispensers for a given robot (using the table) or look up details about a dispenser (using the index)
I have few tables in rethinkdb with very varied datasets. Mostly because over time, out of simple string properties complex objects were created to be more expressive.
When I run a query, I'm making sure that all fields exist, with the hasFields - function. But what if I want to run a RegExp query on my Message property, which can be of type string or object. Of course if it is an object, I don't care about the row, but instead of ignoring it, rethinkdb throws the error:
Unhandled rejection RqlRuntimeError: Expected type STRING but found OBJECT in...
Can I somehow use typeOf to first determine the type, before running the query?
Or what would be a good way to do this?
Your question is not 100% clear to me so I'm going to restate the problem to make sure my solution gets sense.
Problem
Get all documents where the message property is of type object or the message property is a string and matches a particular regular expression (using the match method).
Solution
You basically need an if statement. For that, you can use the r.branch to 'branch' your conditions depending on these things.
Here's a very long, but clear example on how to do this:
Let's say you have these documents and you want all documents where the message property is an object or a string that has the substring 'string'. The documents look like this:
{
"id": "a1a17705-e7b0-4c84-b9d5-8a51f4599eeb" ,
"message": "invalid"
}, {
"id": "efa3e26f-2083-4066-93ac-227697476f75" ,
"message": "this is a string"
}, {
"id": "80f55c96-1960-4c38-9810-a76aef60d678" ,
"not_messages": "hello"
}, {
"id": "d59d4e9b-f1dd-4d23-a3ef-f984c2361226" ,
"message": {
"exists": true ,
"text": "this is a string"
}
}
For that , you can use the following query:
r.table('messages')
.hasFields('message') // only get document with the `message` property
.filter(function (row) {
return r.branch( // Check if it's an object
row('message').typeOf().eq('OBJECT'), // return true if it's an object
true,
r.branch( // Check if it's a string
row('message').typeOf().eq('STRING'),
r.branch( // Only return true if the `message` property ...
row('message').match('string'), // has the substring `string`
true,
false // return `false` if it's a string but doesn't match our regex
),
false // return `false` if it's neither a string or an object
)
)
})
Again this query is long and could be written a lot more elegantly, but it explains the use of branch very clearly.
A shorter way of writing this query is this:
r.table('messages')
.hasFields('message')
.filter(function (row) {
return
row('message').typeOf().eq('OBJECT')
.or(
row('message').typeOf().eq('STRING').and(row('message').match('string'))
)
})
This basically uses the and and or methods instead of branch.
This query will return you all registers on table message that have the field message and the field is String.
Cheers.
r.db('test').table('message').hasFields('message')
.filter(function (row) {
return row('message').typeOf().eq('STRING')
})
all new jsfiddle: http://jsfiddle.net/vJxvc/2/
Currently, i query an api that will return JSON like this. The API cannot be changed for now, which is why I need to work around that.
[
{"timestamp":1406111961, "values":[1236.181, 1157.695, 698.231]},
{"timestamp":1406111970, "values":[1273.455, 1153.577, 693.591]}
]
(could be a lot more lines, of course)
As you can see, each line has a timestamp and then an array of values. My problem is, that i would actually like to transpose that. Looking at the first line alone:
{"timestamp":1406111961, "values":[1236.181, 1157.695, 698.231]}
It contains a few measurements taken at the same time. This would need to become this in my ember project:
{
"sensor_id": 1, // can be derived from the array index
"timestamp": 1406111961,
"value": 1236.181
},
{
"sensor_id": 2,
"timestamp": 1406111961,
"value": 1157.695
},
{
"sensor_id": 3,
"timestamp": 1406111961,
"value": 698.231
}
And those values would have to be pushed into the respective sensor models.
The transformation itself is trivial, but i have no idea where i would put it in ember and how i could alter many ember models at the same time.
you could make your model an array and override the normalize method on your adapter. The normalize method is where you do the transformation, and since your json is an array, an Ember.Array as a model would work.
I am not a ember pro but looking at the manual I would think of something like this:
a = [
{"timestamp":1406111961, "values":[1236.181, 1157.695, 698.231]},
{"timestamp":1406111970, "values":[1273.455, 1153.577, 693.591]}
];
b = [];
a.forEach(function(item) {
item.values.forEach(function(value, sensor_id) {
b.push({
sensor_id: sensor_id,
timestamp: item.timestamp,
value: value
});
});
});
console.log(b);
Example http://jsfiddle.net/kRUV4/
Update
Just saw your jsfiddle... You can geht the store like this: How to get Ember Data's "store" from anywhere in the application so that I can do store.find()?