JSON array transform with JOLT - jolt

I receive following JSON from some REST API:
{
"operation_id" : [ 1405494, 1409934, 1420753 ],
"operation_status" : "success"
}
I want to split operation_id from array to get 1 by 1 value and create new JSON which should look like:
{
"operationsStatus": [
{
"operation_id": 1405494,
"operation_status": "success"
},
{
"operation_id": 1409934,
"operation_status": "success"
},
{
"operation_id": 1420753,
"operation_status": "success"
}
]
}
Can I do it with JOLT spec?

You can walk through the operation_id array by using a shift transformation such as
[
{
"operation": "shift",
"spec": {
"*": {
"operation_id": {
"*": {
"#": "operationsStatus[&1].&2",
"#(2,operation_status)": "operationsStatus[&1].operation_status"
}
}
}
}
}
]
the Result of the demo on https://jolt-demo.appspot.com/

Related

mongodb: updating an object inside array using forEach

I'm having a collection called vehicles whose structure is given below.
[
{
"vehicleType":"car",
"parts":[
{
"partName":"engine",
"buyingPrice":145.00,
"sellingPrice":200.00
},
{
"partName":"brake",
"buyingPrice":50.00,
"sellingPrice":70.00
},
{
"partName":"wheel",
"buyingPrice":70.00,
"sellingPrice":75.00
}
]
},
{
"vehicleType":"bike",
"parts":[
{
"partName":"engine",
"buyingPrice":1450.00,
"sellingPrice":2000.00
},
{
"partName":"brake",
"buyingPrice":507.00,
"sellingPrice":170.00
},
{
"partName":"wheel",
"buyingPrice":70.00,
"sellingPrice":75.00
}
]
},
{
"vehicleType":"car",
"parts":[
{
"partName":"engine",
"buyingPrice":1450.00,
"sellingPrice":2000.00
},
{
"partName":"brake",
"buyingPrice":50.00,
"sellingPrice":170.00
},
{
"partName":"wheel",
"buyingPrice":700.00,
"sellingPrice":750.00
}
]
}
]
I want to update the sellingPrice as 500.00 if the partName is brake and sellingPrice is <= 170.00. I excuted the below query, but it is updating the value only for the 1st object.
db.getCollection("vehicles").find({})
.forEach(function(v){
v.parts.forEach(function(p){
if(p.partName=="brake" && p.sellingPrice<=170.00){
p.sellingPrice=500.00;
print(v);
}
})
})
Below is the output of above query
[
{
"vehicleType":"bike",
"parts":[
{
"partName":"engine",
"buyingPrice":1450.00,
"sellingPrice":2000.00
},
{
"partName":"brake",
"buyingPrice":507.00,
"sellingPrice":500.00
},
{
"partName":"wheel",
"buyingPrice":70.00,
"sellingPrice":75.00
}
]
},
{
"vehicleType":"car",
"parts":[
{
"partName":"engine",
"buyingPrice":1450.00,
"sellingPrice":2000.00
},
{
"partName":"brake",
"buyingPrice":50.00,
"sellingPrice":170.00
},
{
"partName":"wheel",
"buyingPrice":700.00,
"sellingPrice":750.00
}
]
}
]
Don't know what went wrong. Any help is appreciated. Thanks in advance.
I think that the easiest way to do that is with the following query using the positional operator $
db.getCollection('vehicles').updateMany({
"parts.partName": "brake",
"parts.sellingPrice": {
$lte: 170.00
}
},
{
"$set": {
"parts.$.sellingPrice": 500
}
})
In case you can use mongodb cursor methods like forEach try something like this.

Split array inside JSON with JOLT

I have a JSON look like:
[
{
"mainId": 12854,
"subIds": [
25,
26,
27
]
}
]
I want to split values inside subIds to create diffrent rows.
Can I get expected result with JOLT?
[
{
"mainId": 12854,
"subId": 25
},
{
"mainId": 12854,
"subId": 26
},
{
"mainId": 12854,
"subId": 27
}
]
You can walk through the indexes of subIds array while grabbing the value of mainId by #(2,mainId) in order to going up the three two levels, and using [&1] as common factor to reach those indexes such as
[
{
"operation": "shift",
"spec": {
"*": {
"subIds": {
"*": {
"#": "[&1].subId",
"#(2,mainId)": "[&1].mainId"
}
}
}
}
}
]

Jolt for complex JSON transform

Extracting values from first array element and second element and joining both.
Input String:
[
{
"creationDate": "2020-04-01T14:14:32.685+0000",
"factValues": [
{
"Factname": "Medicine",
"factvalue": "1234556",
"sourcePguid": "1"
},
{
"Factname": "Journal",
"factvalue": "123455",
"sourcePguid": "1"
}
]
},
{
"creationDate": "2020-04-01T14:14:32.685+0000",
"factValues": [
{
"Factname": "chemical",
"factvalue": "123455567",
"sourcePguid": "2"
},
{
"Factname": "Rubber",
"factvalue": "123455435",
"sourcePguid": "3"
}
]
}
]
Output excepted:
{
{
"sourcePguid" : "1",
"Medicine":"1234556",
"Journal":"123455"
}, {
"sourcePguid" : "2",
"chemical":"123455567",
"Rubber":"123455435"
}
}
Kindly help me to achieve the expected output.json in spec.json. The spec is not transforming as expected output. I want learn how to use attributes inside the string parser.It would be great.
Hope this might help,
[
{
"operation": "shift",
"spec": {
"*": {
"factValues": {
"*": {
"sourcePguid": "&3.sourcePguid",
"#(0,factvalue)": "&3.#Factname"
}
}
}
}
}, {
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"sourcePguid": "=firstElement(#(1,sourcePguid))"
}
}
}
]
Yet another answer using JSONata
For java: https://github.com/IBM/JSONata4Java
$.factValues{
sourcePguid: {
"sourcePguid": $distinct(sourcePguid),
Factname:factvalue
}
} ~> $each(function($v){$v})

ElasticSearch - Get different types from different indices

I have two indices: A and B.
A has the following types: car, motorbike and van.
B has the following types: bus, car and pickup.
I want to be able to have a single query which gets motorbike and van from A and car and pickup from B.
I want to use a filter to do this and currently, I have:
.filter(
not(
should(
termsQuery("key", Seq("car", "bus"))
)
)
)
But obviously, this will filter car for both indices. I know I can do two separate queries for each index and filter different types for each but I want to avoid this if possible.
Is it possible to do what I am trying to do in a single query?
You can search on index and type by using the special fields _index and _type so once you know that, it's just a matter of putting together a boolean query.
search("_all").query(
boolQuery().should(
boolQuery().must(
termQuery("_index", "A"),
termsQuery("_type", "motorbike", "van")
),
boolQuery().must(
termQuery("_index", "B"),
termsQuery("_type", "car", "pickup")
)
)
)
You can do something like this.
GET _search
{
"query": {
"bool": {
"should": [
{
"bool": {
"filter": [
{
"term": {
"_index": {
"value": "A"
}
}
},
{
"terms": {
"_type": ["motorbike","van"]
}
}
]
}
},
{
"bool": {
"filter": [
{
"term": {
"_index": {
"value": "B"
}
}
},
{
"terms": {
"_type": ["car","pickup"]
}
}
]
}
}
]
}
}
}

Date Filter on elastic search

I'm trying to create a Range Filter on elastic search using the following syntax:
{
"size": 100,
"filter": {
"and": {
"filters": [
{
"range": {
"listingDate": {
"gt": "15/07/2017 16:08:53"
}
}
}
]
}
}
}
The data format is:
"listingDate": "07/07/2015 09:30:00",
However regardless of the filter properties the same incorrect results are being returned by elastic search. I have tried adding the following format:
"format": "dd/MM/yyyy HH:mm:ss"
but I get the same incorrect results.
A fuller example is:
{
"size": 100,
"sort": [
{
"listingDate": {
"order": "asc"
}
}
],
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "Event"
}
},
{
"range": {
"listingDate": {
"gte": "15/07/2015 16:08:53"
}
}
},
{
"range": {
"endDate": {
"gte": "15/07/2015 16:08:53"
}
}
}
]
}
},
"filter": {
"and": {
"filters": [
{
"terms": {
"departments": [
"2393"
]
}
}
]
}
}
}
In JSON documents, dates are represented as strings. Elasticsearch uses a set of preconfigured formats to recognize and parse these strings into a long value representing milliseconds-since-the-epoch in UTC. It might be possible that your date field might not be listed in the set of preconfigured ES date formats.
Formatted dates will be parsed using the format specified on the date field by default, but it can be overridden by passing the format parameter to the range query.
{
"range" : {
"listingDate" : {
"gte": "07/07/2015 09:30:00",
"format": "dd/MM/yyyy HH:mm:ss"
}
}
}
let suppose "arr" argument have a date range e.g. ["2019-07-10","2019-07-11"]
let start_date_query;
let range=[];
if ( arr.date_from ){
if(arr.date_from[1]){
range.push({
"range":{
"start_date":{ "gte":arr.date_from[0] }
}
});
range.push({
"range":{
"end_date":{ "lte": arr.date_from[1] }
}
});
start_date_query = {
"query": {
"constant_score": {
"filter": {
"bool": {
"must":range
}
}
}
};
}
}
}