In Redisgraph, how can I store the numeric value of 0? - cypher

I'm using Redisgraph. I'm using this query:
MERGE (p:Person { age: 0 } )
RETURN p
But what I get is age: "".
If I query:
MERGE (p:Person { age: 12 } )
RETURN p
This correctly store age: 12 (without quotes).
How can I store the numeric value of 0?
Thank you!

A minimal example which create a node with an attribute with the value 0 and retrieves it using redisgraph.js
const RedisGraph = require("redisgraph.js").Graph;
let graph = new RedisGraph("G");
(async () =>{
await graph.query("CREATE (:L {v:0})");
let res = await graph.query("MATCH (a) RETURN a, a.v");
while (res.hasNext()) {
let record = res.next();
console.log(record.get("a"));
console.log(record.get("a.v"));
}
graph.deleteGraph();
graph.close();
})();
Output:
Node { id: 1, label: undefined, properties: { v: 0 } }
0
#albertoSpinella would you mind sharing a reproducible snippet?

Related

How to Add a new field to nested jsonb object in Node-Postgres using parameters?

There is a table A and jsonb field 'context', it looks like:
{
"variable": {},
"other_stuff": {}
}
I need to add a new property to 'varialbe' every time i run query. So It should do smth like:
query1
{
"variable": {
"var1": "var1Value"
},
"other_stuff": {}
}
query2
{
"variable": {
"var1": "var1Value1",
"var2": "var1Value2"
},
"other_stuff": {}
}
And if variable already has this field, it should replace it.
I run this sql, and it works:
let sql = UPDATE chatbots.A SET context = context || jsonb_set(context, '{variable, var1}', 'var1Value1')
It works but when i need to replace 'var1' and 'var1Value1' by parameters ($1 and $2) - it doesn't work (in node-postgres)
I realized that i can replace second parameter by
to_jsonb($2::text)
But what should i do with the first one?
My javascript code
async setUsersVariables(params: {users: ChatUser[], variable_name: string, variable_value: string}) {
const {users, variable_name, variable_value} = params
if (!users.length) return false
let sql = "UPDATE chatbots.A SET context = context || jsonb_set(context, '{variable, $1}', to_jsonb($2)::text) WHERE chat_user_id IN ( "
const parsedUsers = users.map(e=> e?.chat_user_id)
let sqlParams: any[] = [variable_name, variable_value]
let idx = 3;
({ sql, idx, params: sqlParams } = addSqlArrayParams(sql, parsedUsers, idx, sqlParams));
sql += ` RETURNING chat_id, chat_user_id, platform, platform_user_id`;
const filteredUsers: any = (await this.pool.query(sql, sqlParams)).rows
return filteredUsers
}

Highcharts with decrease order in each interval

Is it possible to create a graph sorted in each time interval using Highcharts?
For expample, in this picture for January data will be in order: New York, Tokyo, London, Berlin. The same for each months - data should be shown decrease order
Highcharts doesn't have a built-in function to do that, but for example you can use the render event and organize columns, by changing their positions in the way you need.
events: {
render: function() {
var series = this.series,
longestSeries = series[0],
sortedPoints = [],
selectedPoints = [];
// find a series with the highest amount of points
series.forEach(function(s) {
if (s.points.length > longestSeries.points.length) {
longestSeries = s;
}
});
longestSeries.points.forEach(function(point) {
series.forEach(function(s) {
selectedPoints.push(s.points[point.index]);
});
sortedPoints = selectedPoints.slice().sort(function(a, b) {
return b.y - a.y;
});
selectedPoints.forEach(function(selectedPoint) {
if (
selectedPoints.indexOf(selectedPoint) !==
sortedPoints.indexOf(selectedPoint) &&
selectedPoint.graphic
) {
// change column position
selectedPoint.graphic.attr({
x: sortedPoints[selectedPoints.indexOf(selectedPoint)].shapeArgs.x
});
}
});
sortedPoints.length = 0;
selectedPoints.length = 0;
});
}
}
Live demo: https://jsfiddle.net/BlackLabel/tnrch8v1/
API Reference:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
#ppotaczek Thank You for help a lot! I solve my issue, but i had to make some changes to your code:
events: {
render: function() {
if (this.series.length === 0) return
var series = this.series,
longestSeries = series[0],
sortedPoints = [],
selectedPoints = [];
// find a series with the highest amount of points
series.forEach(function(s) {
if (s.points.length > longestSeries.points.length) {
longestSeries = s;
}
});
longestSeries.points.forEach(function(point) {
series.forEach(function(s) {
selectedPoints.push(s.points[point.index]);
});
sortedPoints = selectedPoints.slice().sort(function(a, b) {
return b.y - a.y;
});
selectedPoints.forEach(function(selectedPoint) {
if (
selectedPoints.indexOf(selectedPoint) !==
sortedPoints.indexOf(selectedPoint) &&
selectedPoint.graphic
) {
// change column position
selectedPoint.graphic.attr({
x: selectedPoints[sortedPoints.indexOf(selectedPoint)].shapeArgs.x
});
}
});
sortedPoints.length = 0;
selectedPoints.length = 0;
});
}
},
}
So i changed:
// change column position
selectedPoint.graphic.attr({
x: sortedPoints[selectedPoints.indexOf(selectedPoint)].shapeArgs.x
});
to:
// change column position
selectedPoint.graphic.attr({
x: selectedPoints[sortedPoints.indexOf(selectedPoint)].shapeArgs.x
});

Azure Stream Analytics: Get Array Elements by name

I was wondering if it is possible for me to get the elements of the array by the name of property than the position. For example, this is my incoming data:
{
"salesdata": {
"productsbyzone": {
"zones": [{
"eastzone": "shirts, trousers"
},
{
"westzone": "slacks"
},
{
"northzone": "gowns"
},
{
"southzone": "maxis"
}
]
}
}
}
I intend to move this to a SQL database and I have columns within the database for each zone. The problem is that the order of different zones changes within each json. I was successfully using the following query until I realized that the position of the zones changes within each json:
WITH
salesData AS
(
SELECT
(c.salesdata.productsbyzone.zone,0) as eastzone,
(c.salesdata.productsbyzone.zone,1) as westzone,
(c.salesdata.productsbyzone.zone,2) as northzone,
(c.salesdata.productsbyzone.zone,3) as sourthzone,
FROM [sales-data] as c
)
SELECT
eastzone.eastzone as PRODUCTS_EAST,
westzone.westzone as PRODUCTS_WEST,
northzone.northzone as PRODUCTS_NORTH,
southzone.southzone as PRODUCTS_SOUTH
INTO PRODUCTSDATABASE
FROM salesData
Need a way to reference these fields by the name rather than by the position.
I recommend a solution: Use the JavaScript UDF in the azure stream job to complete the columns sort.
Please refer to my sample:
Input data(upset the order):
{
"salesdata": {
"productsbyzone": {
"zones": [{
"westzone": "slacks"
},
{
"eastzone": "shirts, trousers"
},
{
"northzone": "gowns"
},
{
"southzone": "maxis"
}
]
}
}
}
js udf code:
function test(arg) {
var z = arg;
var obj = {
eastzone: "",
westzone: "",
northzone: "",
southzone: ""
}
for(var i=0;i<z.length;i++){
switch(Object.keys(z[i])[0]){
case "eastzone":
obj.eastzone = z[i]["eastzone"];
continue;
case "westzone":
obj.westzone = z[i]["westzone"];
continue;
case "northzone":
obj.northzone = z[i]["northzone"];
continue;
case "southzone":
obj.southzone = z[i]["southzone"];
continue;
}
}
return obj;
}
You can define the order you want in the obj parameter
SQL:
WITH
c AS
(
SELECT
udf.test(jsoninput.salesdata.productsbyzone.zones) as result
from jsoninput
),
b AS
(
SELECT
c.result.eastzone as east,c.result.westzone as west,c.result.northzone as north,c.result.southzone as south
from c
)
SELECT
b.east,b.west,b.north,b.south
INTO
jaycosmos
FROM
b
Output:
Hope it helps you.
You can use GetArrayElement to return array element then access to each property. Please refer the below query
WITH
salesData AS
(
SELECT
GetArrayElement(zones,0) as z
FROM [sales-data] as s
)
SELECT
z.eastzone
z.westzone
z.northzone
z.southzone
FROM PRODUCTSDATABASE
FROM salesData

How group and count elements by lodash

has data
items = {
0: {id:1,name:'foo'},
1: {id:2,name:'bar'},
2: {id:1,name:'foo'}
};
I wont get counted elements like this
result = {
0: {id:1,name:'foo', count:2},
1: {id:2,name:'bar', count:1}
};
lodash has function _.countBy(items, 'name') it's got {'foo': 2, 'bar':1}, i need id too.
If pure JS approach is acceptable, you can try something like this:
Logiic:
Loop over array and copy the object and add a property count and set it to 0.
Now on every iteration update this count variable.
Using above 2 steps, create a hashMap.
Now loop over hashMap again and convert it back to array.
var items = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
var temp = items.reduce(function(p,c){
var defaultValue = {
name: c.name,
id: c.id,
count: 0
};
p[c.name] = p[c.name] || defaultValue
p[c.name].count++;
return p;
}, {});
var result = [];
for( var k in temp ){
result.push(temp[k]);
}
console.log(result)

dojo 1.8: populate select box with items from database including null values

Hi I just want to populate the select or comboBox.
I am able to populate both with the searchAttr to any string from JSON. But not so when there are null values.
JSON string :
[{"batch":"0000001000"},{"batch":"0000"},{"batch":""},{"batch":null}]
dojo code:
var selBatch = new ComboBox //located at the left side of the page and it is the second select box in a row
(
{ id:'ID_selBatch',
value:'',
searchAttr:'batch',
placeHolder:'Select...',
style:{width:'150px'},
}, 'node_selBatch'
);
on(selTest, 'change', function(valueCard)
{
var selectedTest = this.get('displayedValue');
var selBatch = registry.byId('ID_selBatch');
console.debug('Connecting to gatherbatches.php ...');
request.post('gatherbatches.php',
{ data:{nameDB:registry.byId('ID_selPCBA').value, nameCard : valueCard},
handleAs: "json"}).then
(
function(response)
{
var memoStore2 = new Memory({data:response});
selBatch.set('store', memoStore2);
selBatch.set('value','');
console.debug('List of batches per Test is completed! Good OK! ');
},
function(error)
{
alert("Batch's Error:"+error);
console.debug('Problem: Listing batches per Test in select Test is BAD!');
}
);
selBatch.startup();
});
Error :
TypeError: _32[this.searchAttr] is null
defer() -> _WidgetBase.js (line 331)
_3() -> dojo.js (line 15)
_f.hitch(this,fcn)(); -> _WidgetBase.js (line 331)
Please advise though it might strange to have null values populate in the select box but these null values are related to data in other columns in database, so the null values included so that I can apply mysql scripts later. Or do you have other better suggestion?
Clement
You can create a QueryFilter as in this jsfiddle to achieve what you want, but it might be simpler to have two data items. Your original model with possibly null batch properties, and the model you pass to the store which is used by the ComboBox.
But anyway, this can work:
function createQueryFilter(originalQuery, filter) {
return function () {
var originalResults = originalQuery.apply(this, arguments);
var results = originalResults.filter(filter);
return QueryResults(results);
};
}
and
var memoStore = new Memory({
data: data
});
memoStore.query = createQueryFilter(memoStore.query, function (item) {
console.log(item);
return !!item.batch;
});
and the dummy data:
function createData1() {
var data = [];
for (var i = 0; i < 10; i++) {
data.push({
name: "" + i,
batch: (0 === i % 2) ? "batch" + i : null
});
}
return data;
}
Screenshot. The odd numbered batch items are null in my example.