How to filter flight_data in "flight_offers" table based on provided segment IDs in Prisma.io?
I have two tables: "searches" and "flight_offers". The db structure for "searches" is as follows:
CREATE TABLE "searches" (
"id" SERIAL NOT NULL,
"user_id" INTEGER,
"guest_id" INTEGER,
"origin" TEXT NOT NULL,
"destination" TEXT NOT NULL,
"departure_date" TIMESTAMP(3) NOT NULL,
"return_date" TIMESTAMP(3),
"passengers" TEXT NOT NULL,
"cabin_class" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "searches_pkey" PRIMARY KEY ("id")
);
The db structure for "flight_offers" is as follows:
CREATE TABLE "flight_offers" (
"id" SERIAL NOT NULL,
"search_id" INTEGER NOT NULL,
"flight_data" JSONB NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "flight_offers_pkey" PRIMARY KEY ("id")
);
This is an example of what the flight_data column in "flight_offers" table contains:
[
{
"type": "flight-offer",
"id": "3",
"itineraries": [
{
"segments": [
{
"id": "1"
}
]
},
{
"segments": [
{
"id": "2"
}
]
}
],
"price": {
"total": "172.00"
}
},
{
"type": "flight-offer",
"id": "3",
"itineraries": [
{
"segments": [
{
"id": "1"
}
]
},
{
"segments": [
{
"id": "3"
}
]
}
],
"price": {
"total": "172.00"
}
}
]
Given a user ID and an array of segment IDs ["1", "2"], I want to query the last search a user did in the "searches" table and then filter the flight_data column in the "flight_offers" table to only return the object that has segments with matching IDs. I am currently using Prisma.io to manage my database, but I am open to using both Prisma and SQL queries to solve this.
desire result is:
{
"type": "flight-offer",
"id": "3",
"itineraries": [
{
"segments": [
{
"id": "1"
}
]
},
{
"segments": [
{
"id": "2"
}
]
}
],
"price": {
"total": "172.00"
}
}
Thanks
Related
I am very new to MongoDB and I need to do a somewhat complex Update operation on my collection.
I have this kind of collection:
[
{
"Id": 1,
"extension": [
{
"keyName": "Name",
"value": "Bob"
},
{
"keyAge": "Age",
"value": 20
}
]
},
{
"Id": 2,
"extension": [
{
"keyName": "Name",
"value": "Sam"
},
{
"key": "Name",
"value": "Sam"
}
]
},
{
"Id": 3,
"extension": [
{
"keyName": "Age",
"value": 25
},
{
"key": "Age",
"value": 25
}
]
},
{
"Id": 4
}
]
I would like to update any items in the extension array of all documents
so that when an item is found with a key property, to rename it keyAge.
Here is the expected result:
[
{
"Id": 1,
"extension": [
{
"keyName": "Name",
"value": "Bob"
},
{
"keyAge": "Age",
"value": 20
}
]
},
{
"Id": 2,
"extension": [
{
"keyName": "Name",
"value": "Sam"
},
{
"keyAge": "Name",
"value": "Sam"
}
]
},
{
"Id": 3,
"extension": [
{
"keyName": "Age",
"value": 25
},
{
"keyAge": "Age",
"value": 25
}
]
},
{
"Id": 4
}
]
I tried to use $rename in a similar way to this question:
MongoDB rename database field within array
but I get the same error $rename source may not be dynamic array
I think this solution might also apply to me, I tried using it but it's not updating anything on my side, so I guess I cannot understand how to apply that answer to me...
https://stackoverflow.com/a/49193743/215553
Thanks for the help!
I tried to use $rename in a similar way to this question: MongoDB rename database field within array but I get the same error $rename source may not be dynamic array
There is a note in $rename:
$rename does not work if these fields are in array elements.
You can try update with aggregation pipeline starting from MongoDB 4.2,
check condition id key field is exists
$map to iterate loop of extension array
$map to iterate loop of array that is converted from extension object to array in key-value format
$cond check condition if k is key then return keyAge otherwise return current
$arrayToObject back to convert key-value array return from above map to object original format
db.collection.update(
{ "extension.key": { $exists: true } },
[{
$set: {
extension: {
$map: {
input: "$extension",
in: {
$arrayToObject: {
$map: {
input: { $objectToArray: "$$this" },
in: {
k: {
$cond: [
{ $eq: ["$$this.k", "key"] }, // check "key" field name
"keyAge", // update new name "keyAge"
"$$this.k"
]
},
v: "$$this.v"
}
}
}
}
}
}
}
}],
{ multi: true }
)
Playground
Question : How to Rename or add new key for existing array object key?
Answer : Inside projection of mongodb query we have map property which will resolve this.
Solution Example :
{
parents: {
$map: {
input: "$parents",
as: "parent",
in: {
caaUserId: "$$parent._id",
email: "$$parent.email",
countryCode: "$$parent.countryCode",
mobile: "$$parent.mobile",
reportType : "single"
}
}
}
}
In this example if we want to rename $parent._id as caaUserId in parents array for each Element.
Then we can use map and define caaUserId like $$parent._id. This whole code will work in mongoose projection of Query.
It should return following :
{
"parents" : [
{
"caaUserId" : "62d17fa164057000149e283f",
"email" : "john.doe#hotmail.com",
"countryCode" : 91,
"mobile": 9876543210,
"reportType":"single",
},
{
"caaUserId" : "6195d50f15ae2b001293c486",
"email" : "akka.ash#hotmail.com",
"countryCode" : 91,
"mobile": 9876543211,
"reportType":"multi",
},
]
}
This is something that works in your case. Might not be the most readable though.
import json
data = json.loads(strdata)
for entry in data:
if 'extension' in entry:
for x in entry['extension']:
for k, v in x.items():
if k == 'key':
x['keyAge'] = x.pop(k)
I'm new with Dynamodb and I don't get it how to make a query to this database.
The table is ave and the structure is:
{
"abuelaMaterna": {
"id": "galloselcomandante-gmail.com#8308",
"nombre": null,
"placa": 8308
},
"abuelaPaterna": {
"id": "galloselcomandante-gmail.com#8389",
"nombre": null,
"placa": 8389
},
"abueloMaterno": {
"id": "galloselcomandante-gmail.com#2874",
"nombre": "ALI",
"placa": 2874
},
"abueloPaterno": {
"id": "galloselcomandante-gmail.com#2300",
"nombre": "MERLOT",
"placa": 2300
},
"almacen": {
"id": "galloselcomandante-gmail.com#1",
"nombre": "Inventario",
"tipo": "inventario"
},
"almacenes": [
{
"almacen": {
"id": "galloselcomandante-gmail.com#1",
"nombre": "Inventario",
"tipo": "inventario"
},
"fecha": 1540872000
}
],
"color": "Indio",
"createdAt": 1540911765981,
"disponibleCruce": true,
"fechaNacimiento": 1534910400,
"genero": "macho",
"id": "12857657-d82e-4021-8a28-66edaa1bffd3",
"madre": {
"id": "galloselcomandante-gmail.com#8924",
"nombre": null,
"placa": 8924
},
"marcajeColiseo": "10",
"notas": [
{
"fecha": 1550588244.267,
"nota": "Vov"
},
{
"fecha": 1552922635.12,
"nota": "Maca Lo viĆ³ y dijo que es especial no se gasta ya"
}
],
"owner": "galloselcomandante-gmail.com",
"ownerPlaca": "galloselcomandante-gmail.com#10669",
"padre": {
"id": "galloselcomandante-gmail.com#9127",
"nombre": null,
"placa": 9127
},
"pesos": [
],
"placa": 10669,
"tipoTuza": "Peine",
"updatedAt": 1540911765981,
"viva": true
}
The table have thousands elements and I want all the items where owner is equals to example#gmail.com
I already did a research in AWS Docs but I don't know how to make it work. I'm using 'aws-sdk` in Nodejs, I did a 'dotClient.scan' but it's not enough
To a look here for some examples using node.js. The problem you have with your key is that the ID looks to be a compound value. You cannot do a begins_with() on the partition key. You can on the sort key though. So you might need to rethink your schema design to put the email as the partition key and the number after the # as the sort key. Without knowing your access patterns it is difficult to say if that will create a hot key in your database.
I have data like below:-
data = [
{
"name": "test4",
"datapoints": [
[currentTimestamp, count]
],
"tags": {
"name" : "MyName",
"dept" : "Engineering",
"city" : "Delhi",
"state": "Delhi",
"country" : "India"
}
}
]
And I am sending data to KairosDB server by using python script like this -
response = requests.post("http://localhost:8080" + "/api/v1/datapoints", json.dumps(data))
I know this data will be stored in three different tables:-
1. string_index
2. row_keys
3. data_points
And my query is :-
{
"metrics": [
{
"tags": {},
"name": "test4",
"aggregators": [
{
"name": "sum",
"sampling": {
"value": "1",
"unit": "milliseconds"
}
}
]
}
],
"plugins": [],
"cache_time": 0,
"start_absolute": 1529346600000
}
Now I want to know that how data will get fetched from those three tables, I mean what will the flow of data retrieval from Cassandra.
Thanks In Advance.
I'm migrating data from Mongo to Arango and I need to reproduce a $group aggregation. I have successfully reproduced the results but I'm concerned that my approach maybe sub-optimal. Can the AQL be improved?
I have a collection of data that looks like this:
{
"_id" : ObjectId("5b17f9d85b2c1998598f054e"),
"department" : [
"Sales",
"Marketing"
],
"region" : [
"US",
"UK"
]
}
{
"_id" : ObjectId("5b1808145b2c1998598f054f"),
"department" : [
"Sales",
"Marketing"
],
"region" : [
"US",
"UK"
]
}
{
"_id" : ObjectId("5b18083c5b2c1998598f0550"),
"department" : "Development",
"region" : "Europe"
}
{
"_id" : ObjectId("5b1809a75b2c1998598f0551"),
"department" : "Sales"
}
Note the value can be a string, Array or not present
In Mongo I'm using the following code to aggregate the data:
db.test.aggregate([
{
$unwind:{
path:"$department",
preserveNullAndEmptyArrays: true
}
},
{
$unwind:{
path:"$region",
preserveNullAndEmptyArrays: true
}
},
{
$group:{
_id:{
department:{ $ifNull: [ "$department", "null" ] },
region:{ $ifNull: [ "$region", "null" ] },
},
count:{$sum:1}
}
}
])
In Arango I'm using the following AQL:
FOR i IN test
LET FIELD1=(FOR a IN APPEND([],NOT_NULL(i.department,"null")) RETURN a)
LET FIELD2=(FOR a IN APPEND([],NOT_NULL(i.region,"null")) RETURN a)
FOR f1 IN FIELD1
FOR f2 IN FIELD2
COLLECT id={department:f1,region:f2} WITH COUNT INTO counter
RETURN {_id:id,count:counter}
Edit:
The APPEND is used to convert string values into an Array
Both produce results that look like this;
{
"_id" : {
"department" : "Marketing",
"region" : "US"
},
"count" : 2.0
}
{
"_id" : {
"department" : "Development",
"region" : "Europe"
},
"count" : 1.0
}
{
"_id" : {
"department" : "Sales",
"region" : "null"
},
"count" : 1.0
}
{
"_id" : {
"department" : "Marketing",
"region" : "UK"
},
"count" : 2.0
}
{
"_id" : {
"department" : "Sales",
"region" : "UK"
},
"count" : 2.0
}
{
"_id" : {
"department" : "Sales",
"region" : "US"
},
"count" : 2.0
}
Your approach seems alright. I would suggest to use TO_ARRAY() instead of APPEND() to make it easier to understand though.
Both functions skip null values, thus it is unavoidable to provide some placeholder, or test for null explicitly and return an array with a null value (or whatever works best for you):
FOR doc IN test
FOR field1 IN doc.department == null ? [ null ] : TO_ARRAY(doc.department)
FOR field2 IN doc.region == null ? [ null ] : TO_ARRAY(doc.region)
COLLECT department = field1, region = field2
WITH COUNT INTO count
RETURN { _id: { department, region }, count }
Collection test:
[
{
"_key": "5b17f9d85b2c1998598f054e",
"department": [
"Sales",
"Marketing"
],
"region": [
"US",
"UK"
]
},
{
"_key": "5b18083c5b2c1998598f0550",
"department": "Development",
"region": "Europe"
},
{
"_key": "5b1808145b2c1998598f054f",
"department": [
"Sales",
"Marketing"
],
"region": [
"US",
"UK"
]
},
{
"_key": "5b1809a75b2c1998598f0551",
"department": "Sales"
}
]
Result:
[
{
"_id": {
"department": "Development",
"region": "Europe"
},
"count": 1
},
{
"_id": {
"department": "Marketing",
"region": "UK"
},
"count": 2
},
{
"_id": {
"department": "Marketing",
"region": "US"
},
"count": 2
},
{
"_id": {
"department": "Sales",
"region": null
},
"count": 1
},
{
"_id": {
"department": "Sales",
"region": "UK"
},
"count": 2
},
{
"_id": {
"department": "Sales",
"region": "US"
},
"count": 2
}
]
I need to write a Select query for the below JSON data in Azure DatabaseDB.
{
"Result": [
{
"media": [
{
"url": "https://someurl.com",
"thumb_url": "https://someurl.com",
"id": "f545f874-a9b4-4573-a0b0-b2d50a7994e0",
"removed": false,
"size": 133454,
"length": 0,
"type": "IMG",
"avail": true,
"has_thumb": true,
"tagged_chi": [
{
"chi_id": "1069b9ef-1028-45f4-b9a1-a40e0d438f4e",
"tag_x": 262.048,
"tag_y": 157.472,
"tag_by": "d481a522-6e2f-4dc6-8aeb-bc87cf27287d",
"created": 1486723018,
"last_updated": 1486723018
},
{
"chi_id": "7102fc10-62e8-4d0a-9fcf-35645253fcef",
"tag_x": 231.648,
"tag_y": 146.528,
"tag_by": "d481a522-6e2f-4dc6-8aeb-bc87cf27287d",
"created": 1486723018,
"last_updated": 1486723018
}
],
"created": 1486723012,
"last_updated": 1486723017
}
],
"id": "23bcd070-0f64-4914-8bc1-d5e936552295",
"acc_id": "d481a522-6e2f-4dc6-8aeb-bc87cf27287d",
"chi_id": "7102fc10-62e8-4d0a-9fcf-35645253fcef",
"is_note": false,
"title": "",
"when": -2147483648,
"loc_id": null,
"col_id": null,
"comment": null,
"removed": false,
"created": -2147483648,
"last_updated": -2147483648,
"note_type": null,
"note_value": null
},
{
"media": [
{
"url": "https://someurl.com",
"thumb_url": "https://someurl.com",
"id": "7665b921-2790-496b-a70f-30afae43d8c6",
"removed": false,
"size": 6872977,
"length": 0,
"type": "IMG",
"avail": true,
"has_thumb": true,
"tagged_chi": [
{
"chi_id": "1069b9ef-1028-45f4-b9a1-a40e0d438f4e",
"tag_x": 2305.152,
"tag_y": 686.5653,
"tag_by": "d481a522-6e2f-4dc6-8aeb-bc87cf27287d",
"created": 1486976119,
"last_updated": 1486976119
},
{
"chi_id": "7102fc10-62e8-4d0a-9fcf-35645253fcef",
"tag_x": 1070.757,
"tag_y": 1038.741,
"tag_by": "d481a522-6e2f-4dc6-8aeb-bc87cf27287d",
"created": 1486976119,
"last_updated": 1486976119
}
],
"created": 1486976100,
"last_updated": 1486976118
}
],
"id": "58fa3c58-5508-4371-83f4-405332c636e1",
"acc_id": "d481a522-6e2f-4dc6-8aeb-bc87cf27287d",
"chi_id": "7102fc10-62e8-4d0a-9fcf-35645253fcef",
"is_note": false,
"title": "",
"when": -2147483648,
"loc_id": null,
"col_id": null,
"comment": null,
"removed": false,
"created": -2147483648,
"last_updated": -2147483648,
"note_type": null,
"note_value": null
}
],
"Continuation": null
}
I was trying something like below but it is not working for me. I want the data matched to Media => tagged_chil => id
Query suggested by, #peter-tirrell:
string.Format("select c.id, c.acc_id, c.chi_id, c.is_note, c.title, c.loc_id, c.media, t from c JOIN m IN c.media JOIN t IN m.tagged_chi where c.chi_id = '{0}' OR t.chi_id = '{0}'", childId)
Minor changes in #peter-tirrell's query:
string.Format("select c.id, c.acc_id, c.chi_id, c.is_note, c.title, c.loc_id, c.media, t from c JOIN m IN c.media JOIN t IN m.tagged_chi where c.chi_id = '{0}' OR ( t.chi_id != c.chi_id AND t.chi_id = '{0}')", childId)
I am getting duplicate records if the c.child and t.child both are having same values.
You could potentially use JOINs to flatten the structure which might help with querying, too. Something like:
select
c.id,
c.acc_id,
c.chi_id,
c.is_note,
c.title,
c.loc_id,
m,
t
from c JOIN m IN c.media
JOIN t IN m.tagged_chi
where c.chi_id = {0} OR t.id = {0}
Then you can select out whichever specific data fields you need.
Base on my experience, your query code will return null. Because ARRAY_CONTAINS it will return a Boolean indicating whether the array contains the specified value. That means your query code can be short as SELECT * FROM TimelineEvent t WHERE OR ARRAY_CONTAINS ( t.media, true) that will return null in your case.
Please have a try to use the following code:
SELECT * FROM TimelineEvent t WHERE ARRAY_CONTAINS ( t.media[0].tagged_chi, {
"id":"0af23202-07f9-40a0-90ba-d2e2f6679331"
})
We also could use UDFs to implement it with customized code, more detail about UDF,please refer to document.