Replace JSON response value ID by the object. [CakePHP 3] - json

Sorry, if the title sounds confusing, I tried my best.
Right now I have this :
{
"success": true,
"data": {
"id_reservation": 101,
"id_venue": 2,
"id_user": 67
}
}
When GETing a reservation from my API, what I'm looking for is
{
"success": true,
"data": {
"id_reservation": 101,
"venue": {
"id_venue": 2,
"venue_name": "TEST",
"location": "TEST",
"venue_type": "TEST"
},
"id_user": 67
}
}
I want to have the object using the ID in my JSON response, how could I achieve this with CakePHP 3?

I guess you're getting the Venue Models with a \Cake\ORM\Query or the object VenuesTable.
You also need to load the associations' Reservation and User, you should read this documentation: Loading Associations
You have to use the contain method like this :
$venueEntity = $this->Venues
->find()
->contain([
'Reservations',
'Users',
])
// then your conditions
->where(['venue_id' => $venueId])
->first();

"Venue" looks like a related table. So you need to make a find requesting all related models. To ensure receiving what you want make a join in the find and set in the "fields" those you want.

Related

Adding multiple entries/rows with knex mysql

I get the following data from the req.body:
{
"user_id": "1",
"user_name": "jkalandarov",
"email": "jkalandarov#gmail.com",
"courses": [
{
"course_id": 1,
"course_name": "English",
"course_price": 265
},
{
"course_id": 2,
"course_name": "Node.js",
"course_price": 200
},
{
"course_id": 3,
"course_name": "Backend Developement",
"course_price": 300
}
]
}
I want to insert this data into three rows with the help of knex into mysql database table like this with a single query:
Any ideas?
Thanks in advance!
Assuming you already have your knex connection set up, it should simply allow you to pass an array of objects into the insert function to insert multiple rows with a single statement. https://knexjs.org/#Builder-insert
Step 1: Build an array of objects
const objectsToInsert = req.body.courses.map(course => {
return {
user_id: req.body.user_id,
user_name: req.body.user_name,
email: req.body.email,
...course
}
});
Step 2: Insert them using your knex connection
await knex('your_table_name').insert(objectsToInsert);
This should insert those three rows into your table in a single query.
As this data is coming directly from the request body it is obviously also a good idea to add some validation here but that feels out of scope for your original question.

search in elastic search index created using a json file

I pushed a json file ( as shown below ) to ES using the following code :
with open('test.json','rb') as payload:
headers = {'content-type': 'application/json'}
r = requests.post('http://localhost:9200/test_nest_json/1',data=payload, verify=False, headers=headers)
{
"data": [
{
"keyword": "abc",
"lists": [
{
"item_val": "some_val"
}
],
"another_key": "some_key"
},
{
"keyword": "xyz",
"lists": [
{
"item_val":"another_val"
}
],
"another_key": "pqr"
}
]
}
I tried updating the mappings and used the term query but still it results in displaying all the indices. I am not able to query only one keyword like "data.keyword" = "abc" using term query.
Looks like you are having a problem with nested object
https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-objects.html
The reason for this cross-object matching, as discussed in Arrays of
Inner Objects, is that our beautifully structured JSON document is
flattened into a simple key-value format in the index
So the effective document stored looks like this:
{
"data.keyword": [ abc, xyz ],
"data.another_key": [ some_key, pqr ],
}
Which means the query you posted will match any document, as long as at least one of the nested object contains the xyz keyword. I recommend reading the link above for clarification.
This is what worked for me :
es.indices.refresh(index="test-index")
with open('abc.json','rb') as payload:
json_data = json.load(payload);
leng = len(json_data["data"])
for i in range (leng):
doc = json.dumps(json_data["data"][i]);
res = es.index(index="sample-index", doc_type='pdf',id=str(uuid.uuid4()), body=doc)
I am parsing the json and extracting the array items one by one and push it to ElasticSearch.
{
"keyword": "abc",
"lists": [
{
"item_val": "some_val"
}
],
"another_key": "some_key"
},
Still looking for an optimised solution.

Json array in mongoDB

I want to get objects according to an ID they have in an array in a json file in mongodb.
I tried a lot of ways to get them with no success:
db.collection.find({"Id":"2"})
db.collection.find({"Messages.Id":"2"})
db.collection.find({"Messages":{$elemMatch:{"Id":"2"}}})
db.collection.find({"Messages.Id":{$elemMatch:{"Id":"2"}}})
{
"Messages" : [
{
"text":"aaa",
"Id" : [ "1", "2" ]
},
{
"texts" : "bbb",
"Id" : [ "1", "3" ]
}
]
}
Even though that's how it's supposed to be done according to the mongodb documentation.
So I thought something was wrong with my json design (I tried changing it but that didn't help either).
Can anyone suggest to me a good design or query to get the objects with a certain id will work?
UPDATE:
I want for example that if in the query i request the id 2
only the first message and all of it will be displayed (I don't mind if the Id field wont be displayed)
{
"text":"aaa",
"Id":["1","2"]
}
To find single elements that match you will need to utilize the positional operator ($).
db.collection.find({"Messages.Id": "2"}, {"Messages.$": 1, _id: 0})
For finding multiple matches, you would use the aggregation pipeline:
db.collection.aggregate([
{ $unwind: "$Messages" },
{ $match: {"Messages.Id": "1"}},
{ $group: { _id: null, messages: { $push: "$Messages"}}}
])

How to load multidimensional / nested json into a store?

So I'm trying to load the data received from a webservice into a sencha touch 2 store.
The data is nested JSON, however it is made to include multiple dataArrays.
I am working with sencha touch 2.3.1, somewhat equal to Ext JS 4.2. I don't have that much experience with sencha yet, but I'm getting there. I decided to go for MVC, so I'd like the answers to be as close to this as possible :).
This is the example JSON I am using:
[
{
"DataCollection": {
"DataArrayOne": [
{
"Name": "John Smith",
"Age": "19"
},
{
"Name": "Bart Smith",
"Age": "16"
}
],
"DataArrayTwo": [
{
"Date": "20110601",
"Product": "Apple",
"Descr": "",
"Remark": ""
},
{
"Date": "20110601",
"Product": "Orange",
"Descr": "",
"Remark": ""
},
{
"Date": "20110601",
"Product": "Pear",
"Descr": "",
"Remark": ""
}
],
"DataArrayThree": [
{
"SomeTotalCost": "400,50",
"IntrestPercentage": "3"
}
]
}
}
]
Through only one call, I get this json. I don't want to cause any unnecessary traffic so I hope to be able to use the data somehow.
I want to be able to use each DataArray on its own.
The data gets sent to the store through its proxy:
Ext.define("MyApp.store.myDataObjects", {
extend: "Ext.data.Store",
config: {
model: "MyApp.model.myDataObject",
proxy: {
reader: {
type: "json",
rootProperty: "DataCollection"
},
type: "ajax",
api: {
read: "https://localhost/Service.svc/json"
},
limitParam: false,
startParam: false,
pageParam: false,
extraParams: {
id: "",
token: "",
filter: ""
},
writer: {
encodeRequest: true,
type: "json"
}
}
}
});
I am a bit stuck with the model here. I tried using mappings which would look like this:
config: {
fields: [ {
name: "IntrestPercentage",
mapping: "Calculation.IntrestPercentage",
type: "string"
}
]}
I tried associations as well but to no avail.
According to google chrome console, it doesn't make any objects containing data. I get only 1 object with all values "null".
My endgoal is to be able to show each dataArray in a separate table. So a table for DataArrayOne, a table for DatarrayTwo... The data itself isn't linked. They are only details that have to be shown on a view.
John Smith isn't related to the apples, as in he didn't buy. The apples are just there as an item to be shown.
The possible solutions I've seen yet not understood due to them being outdated are:
ChildStores: You have a master store that receives the data, and then
you split the data to other stores according to rootProperty. I have
no idea how to do this however and I'm not sure if it will work at
all.
Associations, in case I was doing them wrong. I don't think they
are needed because the data isn't linked to each other but it is part
of "DataCollection" though.
Could someone please post an example on how to deal with this unusual(?) kind of nested json.
Or any other solution which will lead to being able to use the 3 dataArrays at will.
Thanks in advance
The best would be to load the complete data with a separate Ext.Ajax.request and then use store.loadData in the success callback. For example:
var data = Ext.decode(response.responseText);
store1.loadData(data[0].DataCollection.DataArrayOne);
store2.loadData(data[0].DataCollection.DataArrayTwo);
store3.loadData(data[0].DataCollection.DataArrayThree);

JSON format problem when using Factual geo data

I'm using Factual api to fetch location data. Their restful service return data in JSON format as follow, but they are not using "usual" JSON format. There's no attribute key, instead, there's a “fields” that explains all the field keys.
So the question is how to retrieve the attribute I need? Please give an example if possible. Thanks in advance.
{
"response": {
"total_rows": 2,
"data": [
[
"ZPQAB5GAPEHQHDy5vrJKXZZYQ-A",
"046b39ea-0951-4add-be40-5d32b7037214",
"Hanko Sushi Iso Omena",
60.16216,
24.73907
],
[
"2TptHCm_406h45y0-8_pJJXaEYA",
"27dcc2b5-81d1-4a72-b67e-2f28b07b9285",
"Masabi Sushi Oy",
60.21707,
24.81192
]
],
"fields": [
"subject_key",
"factual_id",
"name",
"latitude",
"longitude"
],
"rows": 2,
"cache-state": "CACHED",
"big-data": true,
"subject_columns": [
1
]
},
"version": "2",
"status": "ok"
}
If you know the field name, and the data isn't guaranteed to stay in the same order, I would do a transform on the data so I can reference the fields by name:
var fieldIndex = {}
for (key in x.response.fields)
{
fieldIndex[x.response.fields[key]] = key;
}
for (key in x.response.data)
{
alert(x.response.data[key][fieldIndex.name]);
}
// Field map
var _subject_key = 0,
_factual_id = 1,
_name = 2,
_latitude = 3,
_longitude = 4;
// Example:
alert(_json.response.data[0][_factual_id]);
Demo: http://jsfiddle.net/AlienWebguy/9TEJJ/
I work at Factual. Just wanted to mention that we've launched the beta of version 3 of our API. Version 3 solves this problem directly, by including the attribute keys inline with the results, as you would hope. (Your question applies to version 2 of our API. If you're able to upgrade to version 3 you'll find some other nice improvements as well. ;-)