Replacing a value for JSON object in Node.js - node.js

I tried replacing the value for the key "Information" from the below JSON Object using the code
"itsmdata.incidentParamsJSON.IncidentContainerJson.replace("Information",option);"
but getting error as object is not defined (Attachment)
{
"ServiceName": "IM_LogOrUpdateIncident",
"objCommonParameters": {
"_ProxyDetails": {
"ProxyID": 0,
"ReturnType": "JSON",
"OrgID": 1,
"TokenID": null
},
"incidentParamsJSON": {
"IncidentContainerJson": "{\"SelectedAssets\":null,\"Ticket\":{\"Caller_EmailID\":null,\"Closure_Code_Name\":null,\"Description_Name\":\"Account Unlock\",\"Instance\":null},\"TicketInformation\":{\"Information\":\"account locked out\"},\"CustomFields\":null}"
},
"RequestType": "RemoteCall"
}
}

If you try to update properties of itsmdata you can try this
let str = itsmdata.objCommonParameters.incidentParamsJSON.IncidentContainerJson;
itsmdata.objCommonParameters.incidentParamsJSON.IncidentContainerJson = str.replace(/Information/gi, option);

Related

How to filter document by a value in the dictionary in arangodb?

I have following structure in arangodb collection named clientShadow.
{
"_class": "com.syncservice.document.ClientShadow",
"sessions": {
"session-id-2": {
"workspaceId": "workspace-id-1",
"message": {
"lastSynced": 0,
"lastAvailable": 1674630705773
}
},
"session-id-1": {
"workspaceId": "workspace-id-1",
"message": {
"lastSynced": 0,
"lastAvailable": 1674630705773
}
},
"session-id-0": {
"workspaceId": "workspace-id-1",
"message": {
"lastSynced": 0,
"lastAvailable": 1674630705773
}
}
},
"synced": true
}
Here sessions is a map/dictionary of session_id as string and session object as value.
I want to fetch all the sessions from collection where session's lastSynced and lastAvailable aren't same.
I tried following query
FOR doc IN clientShadow
FOR session IN doc['sessions']
FILTER session.message.lastSynced != session.message.lastAvailable
RETURN {'session': session}
But I found out that FOR IN works with collections and gives me following error
Query: AQL: collection or array expected as operand to FOR loop; you provided a value of type 'object' (while executing)
To retain the original data and query structure, don't use ATTRIBUTES, use VALUES:
FOR doc IN clientShadow
FOR session IN VALUES(doc['sessions'])
FILTER session.message.lastSynced != session.message.lastAvailable
RETURN {'session': session}
If you cannot change the data structure, you can use ATTRIBUTES to access the sessions as array:
Edit: Code as fixed by Kshiti Kshitij Dhakal (Attributes returns a list of the names of the attributes)
FOR doc IN clientShadow
FOR session IN ATTRIBUTES(doc['sessions'])
FILTER
doc.sessions[session].message.lastSynced
!= doc.sessions[session].message.lastAvailable
RETURN {'session': doc.sessions[session]}
Old (wrong) suggestion:
FOR doc IN clientShadow
FOR session IN ATTRIBUTES(doc['sessions'])
FILTER session.message.lastSynced != session.message.lastAvailable
RETURN {'session': session}
If you can change the data structure, don't use an object for sessions, but a list:
{
"_class": "com.syncservice.document.ClientShadow",
"sessions": [
{
"sessionId": "session-id-2",
"workspaceId": "workspace-id-1",
"message": {
"lastSynced": 0,
"lastAvailable": 1674630705773
}
},
...
]
}

How can I return all nested objects using python?

I wrote an Elastic query which will check the condition (status="APPROVED") and Gets all approved_by objects.
This is my index (portfolio):
{
"settings": {},
"mappings": {
"portfolio": {
"properties": {
"status": {
"type": "keyword",
"normalizer": "lcase_ascii_normalizer"
},
"archived_at": {
"type": "date"
},
"approved_by": {
"id": "text",
"name":"text"
}
}
}
}
}
Currently I have 60 objects whose status are approved , so when i run the query it will show 60 objects,but in my case i am getting only one object(I debugged the code, total 60 objects are coming as expected, but still returning only single object), please help guys.
My query:
profiles = client.search(index='portfolio', doc_type='portfolio',
scroll='10m', size=1000,
body={
"query": {"match": {"status": "APPROVED"}}
})
sid = profiles['_scroll_id']
scroll_size = len(profiles['hits']['hits'])
while scroll_size > 0:
for info in profiles['hits']['hits']:
item = info['_source']
approved_by_obj = item.get('approved_by')
if approved_by_obj:
return (jsonify({"approved_by": approved_by_obj}))
Expected o/p format:
{
"approved_by": {
"id": "system",
"name": "system"
}
}
You're getting only one result because you're returning from your loop, effectively breaking out of it completely.
So, instead of returning from it, append the found approved_by_object to a list of your choice and then return that 60-member list:
profiles = client.search(index='portfolio', doc_type='portfolio',
scroll='10m', size=1000,
body={
"query": {"match": {"status": "APPROVED"}}
})
sid = profiles['_scroll_id']
scroll_size = len(profiles['hits']['hits'])
approved_hits_sources = [] # <-- add this
while scroll_size > 0:
for info in profiles['hits']['hits']:
item = info['_source']
approved_by_obj = item.get('approved_by')
if approved_by_obj:
approved_hits_sources.append({"approved_by": approved_by_obj}) # <--- append and not return
return jsonify({"approved_hits_sources": approved_hits_sources})

How to search in anonymous and nested array using find or findAll in groovy's closures using REST-Assured library?

I have following JSON response anonymous body and I need to parse nested arrays dynamically to retrieve a key's value based on a condition by using find or findAll in the groovy's closures
[
{
"children": [
{
"attr": {
"reportId": "1",
"reportShortName": "ABC",
"description": "test,
}
},
{
"attr": {
"reportId": "2",
"reportShortName": "XYZ",
"description": "test",
}
}
}
]
I've tried the following ways and had no luck to retrieve the reportId key's value from the JSON response
package com.src.test.api;
import static io.restassured.RestAssured.given;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
public class GetReportId {
public void getReportId(String reportName) throws Exception {
String searchReports = "http://localhost:8080/reports";
Response resp=given().request().when().get(searchReports).then().extract().response();
JsonPath jsonPath = new JsonPath(resp.asString());
String reportId1 =jsonPath.get("$.find{it.children.contains(restAssuredJsonRootObject.$.children.find{it.attr.reportShortName == 'ABC'})}.attr.reportId");
String reportId2 = jsonPath.get("$.find{it.children.attr.reportShortName.contains(restAssuredJsonRootObject.$.children.find{it.attr.reportShortName.equals('XYZ')}.attr.reportShortName)}.attr.reportId");
System.out.println("ReportId: " + reportId1);
}
}
There could be multiple JSON objects in the parent anonymous array and need to make use of find or findAll within the groovy closures to get the reportId
Need to get the reportId, but seems that something is wrong. Any help would be appreciated.
Assuming you want all the reportIds
List<String> reportIds = jsonPath.get("children.flatten().attr.reportId");
will give you what you want, even it the parent anonymous array has multiple entries.
I tested with the following JSON
[
{
"children": [
{
"attr": {
"reportId": "1",
"reportShortName": "ABC",
"description": "test"
}
},
{
"attr": {
"reportId": "2",
"reportShortName": "XYZ",
"description": "test"
}
}
]
},
{
"children": [
{
"attr": {
"reportId": "3",
"reportShortName": "DEF",
"description": "test"
}
},
{
"attr": {
"reportId": "4",
"reportShortName": "IJK",
"description": "test"
}
}
]
}
]
and it gives me ["1", "2", "3", "4"] i.e. reportIds from all the children
If you know the index of the reportId you're looking for then you can use it like so:
String reportId = jsonPath.get("children.flatten().attr.reportId[0]");
If you're looking for the reportId of a particular report you can do that too:
String reportId = jsonPath.get("children.flatten().attr.find{it.reportShortName == 'ABC'}.reportId")
will give you "1".
Note: The type of the variable you assign the results to are important for type inference and casting. For example, you CANNOT do:
String [] reportIds = jsonPath.get("children.flatten().attr.reportId");
or
int reportId = jsonPath.get("children.flatten().attr.reportId[0]");
Both those things will throw a ClassCastException.

Elasticsearch - MissingMethodException on running distanceInKm on geo_point array

I have an elasticsearch document which has an array of geo_points. I have created the mapping as:
{
"test": {
"properties": {
"locations": {
"type": "geo_point"
}
}
}
}
Now, I am trying to create a query in which I want to do some processing on the array of geo_points. I have created my query like this:
{
"query": {
"filtered": {
"filter": {
"script": {
"script": "sDistance = doc['locations'].values[0].distanceInKm(28.51818,77.096080);"
}
}
}
}
}
I want to calculate the distance of the point (28.51818,77.096080) from the first element in the locations array.
It is giving me this error:
GroovyScriptExecutionException[MissingMethodException[No signature of method: org.elasticsearch.common.geo.GeoPoint.distanceInKm() is applicable for argument types: (java.lang.Double, java.lang.Double) values: [28.51818, 77.09608]]
I tried using sDistance = doc['locations'][0].distanceInKm(28.51818,77.096080); but it also resulted in the same error.
What am I doing wrong here?
Thanks in advance.
Your script should not retrieve the first geo point by itself, but simply call distanceInKm on the locations field directly, like this:
{
"query": {
"filtered": {
"filter": {
"script": {
"script": "sDistance = doc['locations'].distanceInKm(28.51818,77.096080);"
}
}
}
}
}
Under the hood, the first geo point will be retrieved and the distance will be computed on it.

remove objects from array elastic search

I have required to remove object from array that satisfies the condition, I am able to update the object of array on the basis of condition, which is as follow:
PUT twitter/twit/1
{"list":
[
{
"tweet_id": "1",
"a": "b"
},
{
"tweet_id": "123",
"a": "f"
}
]
}
POST /twitter/twit/1/_update
{"script":"foreach (item :ctx._source.list) {
if item['tweet_id'] == tweet_id) {
item['new_field'] = 'ghi';
}
}",
"params": {tweet_id": 123"}
}
this is working
for remove i am doing this
POST /twitter/twit/1/_update
{ "script": "foreach (item : ctx._source.list) {
if item['tweet_id'] == tweet_id) {
ctx._source.list.remove(item);
}
}",
"params": { tweet_id": "123" }
}
but this is not working and giving this error,
ElasticsearchIllegalArgumentException[failed to execute script];
nested: ConcurrentModificationException; Error:
ElasticsearchIllegalArgumentException[failed to execute script];
nested: ConcurrentModificationException
I am able to remove whole array or whole field using
"script": "ctx._source.remove('list')"
I am also able to remove object from array by specifying all the keys of an object using
"script":"ctx._source.list.remove(tag)",
"params" : {
"tag" : {"tweet_id": "123","a": "f"}
my node module elastic search version is 2.4.2 elastic search server is 1.3.2
You get that because you are trying to modify a list while iterating through it, meaning you want to change a list of object and, at the same time, listing those objects.
You instead need to do this:
POST /twitter/twit/1/_update
{
"script": "item_to_remove = nil; foreach (item : ctx._source.list) { if (item['tweet_id'] == tweet_id) { item_to_remove=item; } } if (item_to_remove != nil) ctx._source.list.remove(item_to_remove);",
"params": {"tweet_id": "123"}
}
If you have more than one item that matches the criteria, use a list instead:
POST /twitter/twit/1/_update
{
"script": "items_to_remove = []; foreach (item : ctx._source.list) { if (item['tweet_id'] == tweet_id) { items_to_remove.add(item); } } foreach (item : items_to_remove) {ctx._source.list.remove(item);}",
"params": {"tweet_id": "123"}
}
For people that need this working in elasticsearch 2.0 and up, the nil and foreach don't get recognized by groovy.
So here's a updated version, including a option to replace a item with the same id by a new object.
and also passing it the upsert will make sure the item gets added even if the document doesn't exist yet
{
"script": "item_to_remove = null; ctx._source.delivery.each { elem -> if (elem.id == item_to_add.id) { item_to_remove=elem; } }; if (item_to_remove != null) ctx._source.delivery.remove(item_to_remove); if (item_to_add.size() > 1) ctx._source.delivery += item_to_add;",
"params": {"item_to_add": {"id": "5", "title": "New item"}},
"upsert": [{"id": "5", "title": "New item"}]
}

Resources