Elastic search Parser Error - javascript

I'm trying to construct the following search call in Javascript with no luck, the below works fine so I know my index is setup correctly in ES.
GET /teachersx9/teacher/_search
{
"query": {
"bool": {
"must": [
{ "match_all": {}},
{
"nested": {
"path": "langs",
"score_mode": "max",
"query": {
"bool": {
"must": [
{ "match": { "languagename": "Afrikaans"}}
]
}}}}
]
}}}
However, when trying to create the query on my server using:
app.get('/search', function(req, res) {
var term = req.query.term;//req.param('term');
var urlPath = 'https:.../teachersx9/teacher/_search';
//var obj = {};
var query = {};
query.bool = {};
var match_all = {};
var nested = {path:"langs", score_mode:"max"};
nested.query = {};
nested.query.bool = {};
nested.query.bool.must = [{match: {languagename:term}}];
query.bool.must = [{match_all:match_all}, {nested:nested}];
console.log(query);
request.post({
url: urlPath,
json: true,
body: query
}, function(error, response, body){
if (!error && response.statusCode == 200) {
console.log(body);
res.send(body);
} else {
console.log(body);
res.send(response);
}
});
});
Error I get back from ES as part of the response:
"statusCode": 400,
"body": {
"error": "SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed; shardFailures {[FMwFQZmkIAfOE7X48Q][teachersx9][0]: RemoteTransportException[[Quentin Quire][inet[/172.31.7.165:9300]][indices:data/read/search[phase/query+fetch]]]; nested: SearchParseException[[teachersx9][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"bool\":{\"must\":[{\"match_all\":{}},{\"nested\":{\"path\":\"langs\",\"score_mode\":\"max\",\"query\":{\"bool\":{\"must\":[{\"match\":{\"languagename\":\"Italian\"}}]}}}}]}}]]]; nested: SearchParseException[[teachersx9][0]: from[-1],size[-1]: Parse Failure [No parser for element [bool]]]; }]",
"status": 400
},

bool isn't a valid top-level construct in the Elastic query DSL. You need to wrap it in query.
var body = { query: query }
request.post({
url: urlPath,
json: true,
body: body
})

Related

convert xml data into json in javascript

Need help to convert xml response data into json value and fetch a value from JSON object.
My current code is:
const soapRequest = require('easy-soap-request');
const fs = require('fs');
var convert = require('xml-js');
// example data
const url = 'https://sentro.com/ws/apf/ticketing/Gateway?WSDL';
const sampleHeaders = {
'user-agent': 'sampleTest',
'Content-Type': 'application/html;charset=UTF-8',
};
const xml = fs.readFileSync('Auto_query_request.txt', 'utf-8');
// usage of module
(async () => {
const { response } = await soapRequest({ url: url, headers: sampleHeaders, xml: xml, timeout: 1000 }); // Optional timeout parameter(milliseconds)
const { headers, body, statusCode } = response;
console.log(headers);
//console.log(body);
const options = {ignoreComment: true, alwaysChildren: true};
var result = JSON.parse(convert.xml2json(body, options));
console.log(result);
})();
When i executed above code , i am getting response like below.
{"declaration":{"attributes":{"version":"1.0","encoding":"UTF-8"}},"elements":[{"type":"element","name":"env:Envelope","attributes":{"xmlns:env":"http://schemas.xmlsoap.org/soap/envelope/","xmlns:wsa":"http://www.w3.org/2005/08/addressing"},"elements":[{"type":"element","name":"env:Header","elements":[{"type":"element","name":"wsa:MessageID","elements":[{"type":"text","text":"urn:5C8DC410D18D11EABFB75749E02F1482"}]},{"type":"element","name":"wsa:ReplyTo","elements":[{"type":"element","name":"wsa:Address","elements":[{"type":"text","text":"http://www.w3.org/2005/08/addressing/anonymous"}]},{"type":"element","name":"wsa:ReferenceParameters","elements":[{"type":"element","name":"instra:tracking.compositeInstanceCreatedTime","attributes":{"xmlns:instra":"http://xmlns.oracle.com/sca/tracking/1.0"},"elements":[{"type":"text","text":"2020-07-29T06:19:25.981-05:00"}]}]}]},{"type":"element","name":"wsa:FaultTo","elements":[{"type":"element","name":"wsa:Address","elements":[{"type":"text","text":"http://www.w3.org/2005/08/addressing/anonymous"}]},{"type":"element","name":"wsa:ReferenceParameters","elements":[{"type":"element","name":"instra:tracking.compositeInstanceCreatedTime","attributes":{"xmlns:instra":"http://xmlns.oracle.com/sca/tracking/1.0"},"elements":[{"type":"text","text":"2020-07-29T06:19:25.981-05:00"}]}]}]}]}
with the above results its very difficult for me to fetch data from JSON object.
So i need convert this xml body with proper JSON object as below.
{
"Header": {
"MessageID": "urn:45597DC0D1B511EA8F1C35236A977E2C",
"ReplyTo": {
"Address": "http://www.w3.org/2005/08/addressing/anonymous",
"ReferenceParameters": {
"tracking.compositeInstanceCreatedTime": "2020-07-29T11:05:06.880-05:00"
}
},
"FaultTo": {
"Address": "http://www.w3.org/2005/08/addressing/anonymous",
"ReferenceParameters": {
"tracking.compositeInstanceCreatedTime": "2020-07-29T11:05:06.880-05:00"
}
}
},
"Body": {
"processResponse": {
"payload": {
"RfcProject": {
"IntegrationStatus": "Query - Success",
"Id": "something query",
"Created": "2020-06-16T10:24:18",
"CreatedBy": "something",
"Updated": "2020-07-23T14:14:03",
"UpdatedBy": "somevalue",
"ProjectNum": "something",
and also how to fetch value from JSON Value .Can anyone help here

Consuming data of restAPI using Node

I am calling below restAPI using node JS.
I am using below code.
var Request = require("request");
Request.get("http://localhost:8080/ords/hr/rest-v3/item/Sugar", (error, response, body) => {
if (error) {
return console.dir(error);
}
console.log(response.body);
});
It is giving below output which is correct.
{"items":[{"itemid":101,"itemname":"Sugar","itemcost":32.5}],"hasMore":false,"limit":0,"offset":0,"count":1,"links":[{"rel":"self","href":"http://localhost:8080/ords/hr/rest-v3/item/Sugar"},{"rel":"describedby","href":"http://localhost:8080/ords/hr/metadata-catalog/rest-v3/item/item"}]}
How can I access only itemcost, not entire body. I am new to node so not familiar with many things.
Can you please help me on that.
May be it can help you.
var Request = require("request");
Request.get("http://localhost:8080/ords/hr/rest-v3/item/Sugar", (error, response, body) => {
if (error) {
return console.dir(error);
}
let jsonData = JSON.parse(response.body);
let obj= new Object(jsonData);
obj.items.forEach(itemChild => {
let cost=itemChild.itemcost;
console.log(cost);
})
});
you can iterate the response.body.items and get the costs of all items in the items array like this,
var Request = require("request");
Request.get("http://localhost:8080/ords/hr/rest-v3/item/Sugar", (error, response, body) => {
if (error) {
return console.dir(error);
}
console.log(response.body);
const itemCosts = response.body.items.map(item => item.itemcost);
console.log(itemCosts);
});
Considering your input you can simply do this:
let input = {
"items": [
{
"itemid": 101,
"itemname": "Sugar",
"itemcost": 32.5
}
],
"hasMore": false,
"limit": 0,
"offset": 0,
"count": 1,
"links": [
{
"rel": "self",
"href": "http://localhost:8080/ords/hr/rest-v3/item/Sugar"
},
{
"rel": "describedby",
"href": "http://localhost:8080/ords/hr/metadata-catalog/rest-v3/item/item"
}
]
};
let json = JSON.parse(JSON.stringify(input));
json.items.map(item =>{
console.log(item.itemcost)
})
You can find running solution here

Conditional update to dynamoDB with nested object using node.js

I'm trying to update 3 nested items in a db table,my lambda runs fine and doesnt give any erros,but when a query the table it doesnt show the new values,i´m not sure if im invoking the table or passing the arguments correctly
my partion key/primary key is badgeNumber
my dynamoDB table looks like this:
(the items i'm trying to update are date,hour,register to yyy-mm-dd,hh-mm-ss and true
{
"assistance": [
{
"date": "null",
"hour": "null",
"register": false
}
],
"badgeNumber": "0000",
"data": {
"cardType": "elem",
"firstName": "Moriuks",
"imageURL": "url",
"lastName": "Mora",
"position": "Student"
}
}
the condition to update the items is if register is = false then write the new values to the table.
my code looks like this
pppp
var updateAsisstance = function(day,hour,id){
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName:"someTable",
Key: { badgeNumber : 0000 },
UpdateExpression: "SET #asi[0].#reg = :locVal",
ExpressionAttributeNames: {
'#asi': 'asisstance',
'#reg': 'register',
},
ConditionExpression: "NE(#asi[0].#reg:true)",
ExpressionAttributeValues:{
":date":day,
":hour":hour,
":locVal":true
},
ReturnValues:"UPDATED_NEW"
};
docClient.update(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data);
}
});
};
after defining the funcion,im calling it using
updateAssistance(day,hour,id)
the expected output should look something like this:
"assistance": [
{
"date": "yyyy-MM-DD",
"hour": "HH-MM-SS",
"register": true
}
],
i solved it changing the code,also,my condition expression was wrong...here is what it looks like.
'use strict';
const AWS = require('aws-sdk');
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var hour = (today.getHours()-5) + ":" + today.getMinutes() + ":" + today.getSeconds();
exports.handler = async (event,context) => {
const documentClient = new AWS.DynamoDB.DocumentClient();
let responseBody = "";
let statusCode = 0;
var params = {
TableName:"SomeTable",
Key: { badgeNumber : '0000' },
UpdateExpression: "set assistance[0].register = :n,assistencia[0].date = :date,assistencia[0].hour = :hour",
ExpressionAttributeNames: {
'#asi': 'assistance',
'#reg': 'register'
},
ConditionExpression: "(#asi[0].#reg = :p)",
ExpressionAttributeValues:{
":n":true,
":p":false,
":date":date,
":hour":hour
},
ReturnValues:"UPDATED_NEW"
}
try {
const data = await documentClient.update(params).promise();
responseBody = JSON.stringify(data);
statusCode = 204;
} catch (err) {
responseBody = `Unable to update product: ${err}`;
statusCode = 403;
}
const response = {
statusCode: statusCode,
headers: {
"Content-Type": "application/json"
},
body:responseBody
}
return response
}
this changes the nested values inside my dynamoDB table,if you dont have any its pretty straight forward.

how to get key value pair from body object in javascript while using request module

I am creating an application in which I want to use some data from a JSON, which is generated by another js file. Here is the code which is generating JSON
var request = require('request');
module.exports = {
foo:
request('https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/c1d1e5d6-fe5c-42de-8713-60f272a3b63e?subscription-key=d3d3e4dfa8744be9b4ae47558df8fc5a&timezoneOffset=0&verbose=true&q=hey',function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log(body);
})
};
I am interested in body object, which is giving following contents -
{
"query": "hey",
"topScoringIntent": {
"intent": "Help",
"score": 0.500165462
},
"intents": [
{
"intent": "Help",
"score": 0.500165462
},
{
"intent": "None",
"score": 0.10364107
},
{
"intent": "SearchHotels",
"score": 0.00249445555
},
{
"intent": "ShowHotelsReviews",
"score": 9.451727E-06
}
],
"entities": []
}
Now I want to access value of intent from topScoringIntent element. That to in another JS file. I tried using body[1].intend but it gives undefined.
I am very new to javascript and need very basic code to do this. Please give some suggestions on this. Also plz tell me if this can be solved by body-parser and if yes then how?
Update - Here is the code where I want to use body['topScoringIntent'].intent as global.
require('dotenv-extended').load();
var builder = require('botbuilder');
var restify = require('restify');
var Store = require('./store');
var spellService = require('./spell-service');
var request = require('request');
var myJSON = require("JSON");
var fs = require('fs');
//var window = window;
var request = require("request");
var myJSON = require("JSON");
var globalVar = [];
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create connector and listen for messages
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
server.post('/api/messages', connector.listen());
function getMyBody(url, callback) {
request({
url: 'https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/c1d1e5d6-fe5c-42de-8713-60f272a3b63e?subscription-key=d3d3e4dfa8744be9b4ae47558df8fc5a&timezoneOffset=0&verbose=true&q=hey',
json: true
}, function (error, response, body) {
if (error || response.statusCode !== 200) {
return callback(error || {statusCode: response.statusCode});
}
global.topScoringIntent = body['topScoringIntent'].intent;
//if(body['topScoringIntent'].intent == 'Help');
//console.log('yay');
callback(null, body);
});
}
getMyBody('https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/c1d1e5d6-fe5c-42de-8713-60f272a3b63e?subscription-key=d3d3e4dfa8744be9b4ae47558df8fc5a&timezoneOffset=0&verbose=true&q=hey', function(err, body) {
if (err) {
console.log(err);
}
})
if(body['topScoringIntent'].intent == 'Help');
console.log('success');
This should work for you
console.log(response.topScoringIntent.intent);
body.topScoringIntent.intent will return 'Help'.
To use it globally you can set a var :
var body = {
"query": "hey",
"topScoringIntent": {
"intent": "Help",
"score": 0.500165462
},
"intents": [
{
"intent": "Help",
"score": 0.500165462
},
{
"intent": "None",
"score": 0.10364107
},
{
"intent": "SearchHotels",
"score": 0.00249445555
},
{
"intent": "ShowHotelsReviews",
"score": 9.451727E-06
}
],
"entities": []
}
var result = body.topScoringIntent.intent;
And then use result somewhere else :
console.log(result);

node js + express + jade iterate array

What I'm trying to do is iterate over an array in a jade layout. The layout file is lessons.jade:
each lesson in myLessons
ul.nav.pull-center: li.dropdown.nav.text-center
.btn.btn-default.dropdown-toggle.btn-lg.btn-block(data-toggle="dropdown" aria-expanded="false")= lesson.day
ul.dropdown-menu.col-xs-12
each lessonName in myLessons
li: a(href='/lessons/details')= lessonName.name
li.divider
My view controller file is lessons.js:
var renderLessonPage = function (req, res, responseBody) {
var message;
if (!(responseBody)) {
message = "Lessons API Error!";
} else {
if (responseBody.length < 0) {
message = "No lessons found!";
}
}
res.render('lessons', {
title: 'Lesson page',
pageHeader: {
title: 'Just a page'
},
myLessons: responseBody,
message: message
});
};
module.exports.lessons = function(req, res) {
var requestOptions, path;
path = '/api/locations/' + req.params.locationid + '/lessons/';
requestOptions = {
url: apiOptions.server + path,
method: "GET",
json: {}
};
request(
requestOptions,
function (err, response, body) {
renderLessonPage(req, res , body );
}
);
};
My API controller file contains:
var sendJsonResponse = function (res, status, content) {
res.status(status);
res.json(content);
};
module.exports.lessons = function (req, res) {
loc
.findById(req.params.locationid)
.populate('lessons')
.exec(function (err, location) {
if (!location) {
sendJsonResponse(res, 404, {
"message": "No lessons found!"
});
} else {
response = {
location: {
lessons: location.lessons
// id: req.params.locationid
}
};
sendJsonResponse(res, 200, response);
}
})
};
If I fire up Chrome and browse to the location accessed by the API, I see the following json result:
{
"location": {
"lessons": [
{
"_id": "56d5d947bdb5c3d92ace848c",
"name": "Henk",
"startTime": "13:00",
"endTime": "14:00",
"day": "Tuesday",
"__v": 0
},
{
"_id": "56d5d9dfea5cbcf42a20f87e",
"name": "skaaak",
"startTime": "12:00",
"endTime": "18:00",
"day": "Monday",
"__v": 0
}
]
}
}
If I enable console.log in my jade layout template via - console.log and catch the lesson in myLessons, the exact same thing is outputted in the console. But I just can't use values from the array in my jade layout.
I get one dropdown menu only instead of two, the text isn't populated on the dropdown button, and there are two empty items in the pull down menu.
I tried many things, but most resulted in undefined or properties which couldn't be read.
When you sent result for your request
response = {
location: {
lessons: location.lessons
// id: req.params.locationid
}
};
sendJsonResponse(res, 200, response);
response is object, not array. So when renderLessonPage function render (option myLessons: responseBody) is object.
You can replace your code as below:
response = {
location: {
lessons: location.lessons
// id: req.params.locationid
}
};
sendJsonResponse(res, 200, response.location.lessons);

Categories

Resources