ja and complex json object - node.js

I'm converting a Sdmx xml api output to an Json Object. I try with boot 'xml-js' and 'xml2js' and
the result is a complex object like this:
{
"_declaration": {
"_attributes": {
"version": "1.0",
"encoding": "utf-8"
}
},
"_comment": "NSI Web Service v6.16.0",
"message:Structure": {
"_attributes": {
"xmlns:message": "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message",
"xmlns:structure": "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/structure",
"xmlns:common": "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common"
},
"message:Header": {
"message:ID": {
"_text": "IDREF161"
},
"message:Test": {
"_text": "false"
},
"message:Prepared": {
"_text": "2021-04-11T13:21:40.0658418+02:00"
},
"message:Sender": {
"_attributes": {
"id": "Unknown"
}
},
"message:Receiver": {
"_attributes": {
"id": "Unknown"
}
}
},
"message:Structures": {
"structure:Codelists": {
"structure:Codelist": {
"_attributes": {
"id": "CL_CAUSEMORTE_SL",
"urn": "urn:sdmx:org.sdmx.infomodel.codelist.Codelist=IT1:CL_CAUSEMORTE_SL(1.1)",
"agencyID": "IT1",
"version": "1.1",
"isFinal": "true"
},
"common:Name": [
{
"_attributes": {
"xml:lang": "it"
},
"_text": "Cause di morte - European short list"
},
{
"_attributes": {
"xml:lang": "en"
},
"_text": "European short list of causes of death"
}
],
I can't navigate the structure and retrive elements value in anyway, examples:
console.log(result['message:Structure']);
undefined
console.log(result[2]);
undefined
any help is appreciated,
regards, Maurizio

Related

Filter data using nodejs and elasticsearch

I'm currently facing an issue with my datatable implemented in ReactJS. I'm retrieving data from elasticsearch and populating the datatable with it. The data retrieval process works fine without the filter applied, however, when I apply filters to the data, the datatable remains empty, even though the data _source has matching records.
The structure of the parameters I am sending is as follows:
{
pageIndex: 1,
pageSize: 10,
sort: { order: '', key: '' },
query: '',
filterData: {
analysis: [ '0', '1', '2', '3' ],
threat_level_id: [ '1', '2', '3', '4' ],
}
}
EndPoint:
POST /api/v1/events/public/list
Controller:
exports.getPublicEvents = async (req, res) => {
try {
client.ping()
const { pageIndex, pageSize, sort, query, filterData } = req.body
let esQuery = {
index: 'ns_*',
body: {
query: {
bool: {
must: [
{
match_all: {},
},
],
filter: [],
},
},
from: (pageIndex - 1) * pageSize,
size: pageSize,
},
}
if (query) {
esQuery.body.query.bool.must = [
{
match: {
'Event.info': {
query: query,
fuzziness: 'AUTO',
},
},
},
]
}
if (filterData.analysis.length > 0) {
esQuery.body.query.bool.filter.push({
terms: {
'Event.analysis': filterData.analysis,
},
})
}
if (filterData.threat_level_id.length > 0) {
esQuery.body.query.bool.filter.push({
terms: {
'Event.threat_level_id': filterData.threat_level_id,
},
})
}
let esResponse = await client.search(esQuery)
let data = esResponse.hits.hits.map((hit) => hit._source)
let total = esResponse.hits.total.value
res.status(200).json({
status: 'success',
data: data,
total: total,
})
} catch (error) {
res.status(500).json({
error: 'Error connecting to Elasticsearch',
errorMessage: error.message,
})
}
}
The controller below is without filters and it works just fine.
exports.getPublicEvents = async (req, res) => {
try {
client.ping()
const { pageIndex, pageSize, sort, query } = req.body
let esQuery = {
index: 'ns_*',
body: {
query: {
match_all: {},
},
from: (pageIndex - 1) * pageSize,
size: pageSize,
},
}
if (query) {
esQuery.body.query = {
match: {
'Event.info': {
query: query,
fuzziness: 'AUTO',
},
},
}
}
let esResponse = await client.search(esQuery)
let data = esResponse.hits.hits.map((hit) => hit._source)
let total = esResponse.hits.total.value
res.status(200).json({
status: 'success',
data: data,
total: total,
})
} catch (error) {
res.status(500).json({
error: 'Error connecting to Elasticsearch',
errorMessage: error.message,
})
}
}
ElasticSearech version: 7.17.8
Result of: console.log(JSON.stringify(esQuery))
{
"index": "INDEX_NAME",
"body": {
"query": {
"bool": {
"must": [{ "match_all": {} }],
"filter": [
{ "terms": { "Event.analysis": ["0", "1", "2"] } },
{ "terms": { "Event.threat_level_id": ["1", "2", "3", "4"] } }
]
}
},
"from": 0,
"size": 10
}
}
Data in elascticsearch schema
{
"#version": "1",
"#timestamp": "2023-02-01T14:43:09.997Z",
"Event": {
"info": ".......................",
"description": ".......................",
"analysis": 0,
"threat_level_id": "4",
"created_at": 1516566351,
"uuid": "5a64f74f0e543738c12bc973322",
"updated_at": 1675262417
}
}
Index Mapping
{
"index_patterns": ["INDEX_NAME"],
"template": "TEMPLATE_NAME",
"settings": {
"number_of_replicas": 0,
"index.mapping.nested_objects.limit": 10000000
},
"mappings": {
"dynamic": false,
"properties": {
"#timestamp": {
"type": "date"
},
"Event": {
"type": "nested",
"properties": {
"date_occured": {
"type": "date"
},
"threat_level_id": {
"type": "integer"
},
"description": {
"type": "text"
},
"is_shared": {
"type": "boolean"
},
"analysis": {
"type": "integer"
},
"uuid": {
"type": "text"
},
"created_at": {
"type": "date"
},
"info": {
"type": "text"
},
"shared_with": {
"type": "nested",
"properties": {
"_id": {
"type": "text"
}
}
},
"updated_at": {
"type": "date"
},
"author": {
"type": "text"
},
"Attributes": {
"type": "nested",
"properties": {
"data": {
"type": "text"
},
"type": {
"type": "text"
},
"uuid": {
"type": "text"
},
"comment": {
"type": "text"
},
"category": {
"type": "text"
},
"value": {
"type": "text"
},
"timestamp": {
"type": "date"
}
}
},
"organisation": {
"type": "nested",
"properties": {
"name": {
"type": "text"
},
"uuid": {
"type": "text"
}
}
},
"Tags": {
"type": "nested",
"properties": {
"color": {
"type": "text"
},
"name": {
"type": "text"
}
}
},
"TLP": {
"type": "nested",
"properties": {
"color": {
"type": "text"
},
"name": {
"type": "text"
}
}
}
}
}
}
}
}
Event is a nested field, so you need to use nested queries, like this:
{
"index": "INDEX_NAME",
"body": {
"query": {
"bool": {
"must": [{ "match_all": {} }],
"filter": [
{
"nested": {
"path": "Event",
"query": {"terms": { "Event.analysis": ["0", "1", "2"] }}
}
},
{
"nested": {
"path": "Event",
"query": {"terms": { "Event.threat_level_id": ["1", "2", "3", "4"] }}
}
}
]
}
},
"from": 0,
"size": 10
}
}

Can I define an extend field for response component Swagger?

Current, I use #/components/responses/Default response as reuseable properties for all api defines. But some API need to add more a field but not change default response format. So Can I reUse default response and add more field for response
{
"openapi": "3.0.3",
"path": {
"/login": {
"post": {
"responses": {
200: {
"description": "Successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/responses/defaultResponse"
}
}
}
}
}
}
}
},
"components": {
"schemas" :{
"responseSchema": {
"type": "object",
"properties": {
"httpCode": { "type": "integer" },
"message": { "type": "string" }
}
}
},
"responses": {
"defaultResponse": { "$ref": "#/components/schemas/responseSchema" }
}
}
}
Above is my swagger spec. but with Login, if success I want to put more a field (token) to return token for client, Can I do it with this or have to manual define schema ?
In OpenAPI version 3, you do this with the allOf keyword. Detail document
{
"openapi": "3.0.3",
"info": {
"title": "Example",
"version": "1.0"
},
"paths": {
"/login": {
"post": {
"responses": {
"200": {
"description": "Successful operation",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"$ref": "#/components/responses/defaultResponse"
},
{
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
}
]
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"responseSchema": {
"type": "object",
"properties": {
"httpCode": {
"type": "integer"
},
"message": {
"type": "string"
}
}
}
},
"responses": {
"defaultResponse": {
"$ref": "#/components/schemas/responseSchema"
}
}
}
}

Elasticsearch NodeJs putIndexTemplate API

I'm using elasticsearch 7.13.3 and I want to call the put index template API from my typescript app. I'm using the package "#elastic/elasticsearch": "7.13.0" but I get error for the composition of the call.
From kibana I can execute without any error:
PUT _component_template/template-xxx2
{
"template": {
"mappings": {
"properties": {
"#timestamp": {
"type": "date"
},
"id": {
"type": "keyword"
},
"value": {
"type": "double",
"coerce": false
}
}
}
}
}
PUT _index_template/index-template-xxx2
{
"index_patterns": ["template-xxx2*"],
"template": {
"settings": {
"number_of_shards": 2
},
"mappings": {
"_source": {
"enabled": true
},
"properties": {
"created_at": {
"type": "date",
"format": "EEE MMM dd HH:mm:ss Z yyyy"
}
}
},
"aliases": {
"mydata": { }
}
},
"priority": 600,
"composed_of": ["template-xxx2"],
"version": 3,
"_meta": {
"description": "template-xxx2 description"
}
}
and I want do the same from my node app.
The template creation it's ok:
void this.db.clientDb.indices.putTemplate({
name: `template_${this.index}`,
body: {
mappings: {
properties: {
'#timestamp': {
type: 'date'
},
id: {
type: 'keyword'
},
value: {
type: 'double',
coerce: false
}
}
}
}
});
But I can't find the correct overload for the this.db.clientDb.indices.putIndexTemplate({ API.
This gave me errors: (no overloads match this call)
void this.db.clientDb.indices.putIndexTemplate({
name: '',
index_patterns: ["template-xxx2*"], // --> where should I put this property?
body: {
settings: {
number_of_shards: 2
},
mappings: {
_source: {
enabled: true
}
},
aliases: {
mydata: {}
}
},
priority: 500,
composed_of: ['template-xxx2'], // --> where should I put this property?
version: 3,
_meta: {
description: 'template-xxx2 description'
}
});
I want to do this latest script.
Index templates have been overhauled in 7.8. The previous legacy endpoint was called _template and the new one is called _index_template.
You're mixing calls to the old and the new endpoint, i.e. putTemplate calls the old legacy endpoint and putIndexTemplate calls the new one.
Moreover, the whole template definition needs to go inside body, not at the top level of the call parameters.
So here is what you need to do. First, make this call to store the component template:
void this.db.clientDb.cluster.putComponentTemplate({
"name": "template-xxx2",
"body": {
"template": {
"mappings": {
"properties": {
"#timestamp": {
"type": "date"
},
"id": {
"type": "keyword"
},
"value": {
"type": "double",
"coerce": false
}
}
}
}
}
})
Then store the index template with the following call:
void this.db.clientDb.indices.putIndexTemplate({
"name": "index-template-xxx2",
"body": {
"index_patterns": ["template-xxx2*"],
"template": {
"settings": {
"number_of_shards": 2
},
"mappings": {
"_source": {
"enabled": true
},
"properties": {
"created_at": {
"type": "date",
"format": "EEE MMM dd HH:mm:ss Z yyyy"
}
}
},
"aliases": {
"mydata": { }
}
},
"priority": 600,
"composed_of": ["template-xxx2"],
"version": 3,
"_meta": {
"description": "template-xxx2 description"
}
}
})

GraphQL Query - cannot see nested elements in JSON respone

if anyone can hazard a guess or where to look it would be greatly appreciated.
I can get nested data when I run using graphgl API, however, from my node program it only shows top-level items - does not display the nested elements for the customer and lineitem object.
I am using Koa middle where, with promise response:
router.get('/orders/', async (ctx) => {
const auth = prepareAuth(ctx);
await getOrders(auth).then(response => ctx.body = response.data.data.orders);
console.log(ctx.body.edges)
However from the console it has (customer null and 'object':
[
{
node: {
createdAt: '2020-02-24T12:53:20Z',
customer: null,
name: '#1001',
lineItems: [Object]
}
},
{
node: {
createdAt: '2020-02-24T12:53:50Z',
customer: null,
name: '#1002',
lineItems: [Object]
}
},
{
node: {
createdAt: '2020-03-10T21:11:04Z',
customer: null,
name: '#1003',
lineItems: [Object]
}
}
]
when i use the GraphQL API directly the query works fine and I get full response:
{
"data": {
"orders": {
"edges": [
{
"node": {
"createdAt": "2020-02-24T12:53:20Z",
"customer": {
"displayName": "franko girl"
},
"name": "#1001",
"lineItems": {
"edges": [
{
"node": {
"name": "dance mat red",
"quantity": 4
}
}
]
}
}
},
{
"node": {
"createdAt": "2020-02-24T12:53:50Z",
"customer": {
"displayName": "franko man"
},
"name": "#1002",
"lineItems": {
"edges": [
{
"node": {
"name": "dance mat black",
"quantity": 2
}
}
]
}
}
},
{
"node": {
"createdAt": "2020-03-10T21:11:04Z",
"customer": {
"displayName": "franko man"
},
"name": "#1003",
"lineItems": {
"edges": [
{
"node": {
"name": "dance mat black",
"quantity": 1
}
},
{
"node": {
"name": "dance mat red",
"quantity": 1
}
}
]
}
}
}
]
}
},
Okay, so finally figured this out, for anyone else who stumbles accross this problem, you need to the convert the json object to a string using built in javascript function: JSON.stringify()
from W3schools.com
var obj = { name: "John", age: 30, city: "New York" };
var myJSON = JSON.stringify(obj);

"commands" (shortcuts): is it possible to sort them for `chrome://extensions/shortcuts`?

In my manifest.json I have:
"commands": {
"add": {
"suggested_key": {
"default": "MacCtrl+Shift+A"
},
"description": "__MSG_addToFeed__"
},
"playPause": {
"suggested_key": {
"default": "Alt+P"
},
"description": "__MSG_playPause__"
},
"nextArticle": {
"description": "__MSG_nextArticle__"
},
"nextChunk": {
"suggested_key": {
"default": "Alt+N"
},
"description": "__MSG_nextChunk__"
},
"prevArticle": {
"suggested_key": {
"default": "Alt+B"
},
"description": "__MSG_prevArticle__"
}
}
This is what I get on chrome://extensions/shortcuts
I do not understand how they are sorted - neither by title nor by shortcut. And looks like no way to change that order.
Documentation links:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/commands
https://developer.chrome.com/extensions/commands
Related source code of Chromium: https://github.com/chromium/chromium/blob/2ca8c5037021c9d2ecc00b787d58a31ed8fc8bcb/chrome/browser/resources/md_extensions/keyboard_shortcuts.js
Add numbers to your commands object as they are sorted by their keys.
"commands": {
"1_add": { ... },
"2_playPause": { ... },
"3_nextArticle": { ... },
"4_nextChunk": { ... },
"5_prevArticle": { ... }
}

Resources