Aerospike: lua udf always returns an empty result even if udf return stream without any filtering, etc - lua

Can not understand why aggregateQuery always returns an empty result. Tried to test in aql, the same problem: 0 rows in set.
Indexes are all there.
aql> show indexes
+---------------+-------------+-----------+------------+-------+------------------------------+-------------+------------+-----------+
| ns | bin | indextype | set | state | indexname | path | sync_state | type |
+---------------+-------------+-----------+------------+-------+------------------------------+-------------+------------+-----------+
| "test" | "name" | "NONE" | "profiles" | "RW" | "inx_test_name" | "name" | "synced" | "STRING" |
| "test" | "age" | "NONE" | "profiles" | "RW" | "inx_test_age" | "age" | "synced" | "NUMERIC" |
aql> select * from test.profiles
+---------+-----+
| name | age |
+---------+-----+
| "Sally" | 19 |
| 20 | |
| 22 | |
| 28 | |
| "Ann" | 22 |
| "Bob" | 22 |
| "Tammy" | 22 |
| "Ricky" | 20 |
| 22 | |
| 19 | |
+---------+-----+
10 rows in set (0.026 secs)
aql> AGGREGATE mystream.avg_age() ON test.profiles WHERE age BETWEEN 20 and 29
0 rows in set (0.004 secs)

It seems that you are trying the example here.
There are two problems about the udf script. I paste the code of the lua script :
function avg_age(stream)
local function female(rec)
return rec.gender == "F"
end
local function name_age(rec)
return map{ name=rec.name, age=rec.age }
end
local function eldest(p1, p2)
if p1.age > p2.age then
return p1
else
return p2
end
end
return stream : filter(female) : map(name_age) : reduce(eldest)
end
First, there is no bin named 'gender' in your set, so you got 0 rows after aggregateQuery.
Second, this script isn't doing exactly what the function name 'avg_age' means, it just return the eldest record with name and age.
I paste my code bellow, it just replace the reduce func, and alert the map and filter func to meat the demand. You can just skip the filter process.
function avg_age(stream)
count = 0
sum = 0
local function female(rec)
return true
end
local function name_age(rec)
return rec.age
end
local function avg(p1, p2)
count = count + 1
sum = sum + p2
return sum / count
end
return stream : filter(female) : map(name_age) : reduce(avg)
end
The output looks like bellow :
AGGREGATE mystream.avg_age() ON test.avgage WHERE age BETWEEN 20 and 29
+---------+
| avg_age |
+---------+
| 22 |
+---------+
1 row in set (0.001 secs)

Related

Cypher query aggregate sum of values

I have a Cypher query that shows the following output:
+----------------
| usid | count |
+----------------
| "000" | 1 |
| "000" | 0 |
| "000" | 0 |
| "001" | 1 |
| "001" | 1 |
| "001" | 0 |
| "002" | 2 |
| "002" | 2 |
| "002" | 0 |
| "003" | 4 |
| "003" | 2 |
| "003" | 2 |
| "004" | 4 |
| "004" | 4 |
| "004" | 4 |
+----------------
How can I get the below result with the condition SUM(count) <= 9.
+----------------
| usid | count |
+----------------
| "000" | 1 |
| "001" | 2 |
| "002" | 4 |
| "003" | 8 |
+----------------
Note: I have used the below query to get the 1st table data.
MATCH (us:USER)
WITH us
WHERE us.count <= 4
RETURN us.id as usid, us.count as count;
I don't know how you get your original data, so I will just use a WITH clause and assume the data is there:
// original data
WITH usid, count
// aggregate and filter
WITH usid, sum(count) as new_count
WHERE new_count <= 9
RETURN usid, new_count
Based on the updated question, the new query would look like:
MATCH (us:USER)
WHERE us.count <= 4
WITH us.id as usid, sum(us.count) as count
WHERE new_count <= 9
RETURN usid, count
˙˙˙

Rail Query includes + filter by column

I start in Ruby and Ruby on rails. I am trying to modify the access to this object (below) in base via the form and I will like to filter by the values that are in the table node_tags.
def map
......
nodes = Node.bbox(bbox).where(:visible => true).includes(:node_tags).limit(MAX_NUMBER_OF_NODES + 1)
.....
end
Probably on SQL request
SELECT * FROM nodes n INNER JOIN node_tags nt on n.node_id = nt.node_id where nt.k = 'alert' and nt.v = 'true'
Table nodes
| node_id | latitude | longitude | changeset_id | visible | timestamp | tile | version | redaction_id |
|---------|-----------|-----------|--------------|---------|-----------|------|---------|--------------|
| 11 | 473705641 | 3955487 | 11 | TRUE |
| 12 | 473705641 | 3955487 | 12 | TRUE |
table node_tags
| node_id | k | v |
|---------|-------|------|
| 11 | name | bob |
| 12 | alert | true |
If I understand right, you need to get sql as in your example by ORM (ActiveRecord).
Try this:
nodes = Node.where(:visible => true).join(:node_tags).where("node_tags.k = 'alert' and node_tags.v = 'true'")

Finding root of a tree in a directed graph

I have a tree structure like node(1)->node(2)->node(3). I have name as an property used to retrieve a node.
Given a node say node(3), i wanna retrieve node(1).
Query tried :
MATCH (p:Node)-[:HAS*]->(c:Node) WHERE c.name = "node 3" RETURN p LIMIT 5
But, not able to get node 1.
Your query will not only return "node 1", but it should at least include one path containing it. It's possible to filter the paths to only get the one traversing all the way to the root, however:
MATCH (c:Node {name: "node 3"})<-[:HAS*0..]-(p:Node)
// The root does not have any incoming relationship
WHERE NOT (p)<-[:HAS]-()
RETURN p
Note the use of the 0 length, which matches all cases, including the one where the start node is the root.
Fun fact: even if you have an index on Node:name, it won't be used (unless you're using Neo4j 3.1, where it seems to be fixed since 3.1 Beta2 at least) and you have to explicitly specify it.
MATCH (c:Node {name: "node 3"})<-[:HAS*0..]-(p:Node)
USING INDEX c:Node(name)
WHERE NOT (p)<-[:HAS]-()
RETURN p
Using PROFILE on the first query (with a numerical id property instead of name):
+-----------------------+----------------+------+---------+-------------------------+----------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+-----------------------+----------------+------+---------+-------------------------+----------------------+
| +ProduceResults | 0 | 1 | 0 | p | p |
| | +----------------+------+---------+-------------------------+----------------------+
| +AntiSemiApply | 0 | 1 | 0 | anon[23], c -- p | |
| |\ +----------------+------+---------+-------------------------+----------------------+
| | +Expand(All) | 1 | 0 | 3 | anon[58], anon[67] -- p | (p)<-[:HAS]-() |
| | | +----------------+------+---------+-------------------------+----------------------+
| | +Argument | 1 | 3 | 0 | p | |
| | +----------------+------+---------+-------------------------+----------------------+
| +Filter | 1 | 3 | 3 | anon[23], c, p | p:Node |
| | +----------------+------+---------+-------------------------+----------------------+
| +VarLengthExpand(All) | 1 | 3 | 5 | anon[23], p -- c | (c)<-[:HAS*]-(p) |
| | +----------------+------+---------+-------------------------+----------------------+
| +Filter | 1 | 1 | 3 | c | c.id == { AUTOINT0} |
| | +----------------+------+---------+-------------------------+----------------------+
| +NodeByLabelScan | 3 | 3 | 4 | c | :Node |
+-----------------------+----------------+------+---------+-------------------------+----------------------+
Total database accesses: 18
and on the second one:
+-----------------------+----------------+------+---------+-------------------------+------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+-----------------------+----------------+------+---------+-------------------------+------------------+
| +ProduceResults | 0 | 1 | 0 | p | p |
| | +----------------+------+---------+-------------------------+------------------+
| +AntiSemiApply | 0 | 1 | 0 | anon[23], c -- p | |
| |\ +----------------+------+---------+-------------------------+------------------+
| | +Expand(All) | 1 | 0 | 3 | anon[81], anon[90] -- p | (p)<-[:HAS]-() |
| | | +----------------+------+---------+-------------------------+------------------+
| | +Argument | 1 | 3 | 0 | p | |
| | +----------------+------+---------+-------------------------+------------------+
| +Filter | 1 | 3 | 3 | anon[23], c, p | p:Node |
| | +----------------+------+---------+-------------------------+------------------+
| +VarLengthExpand(All) | 1 | 3 | 5 | anon[23], p -- c | (c)<-[:HAS*]-(p) |
| | +----------------+------+---------+-------------------------+------------------+
| +NodeUniqueIndexSeek | 1 | 1 | 2 | c | :Node(id) |
+-----------------------+----------------+------+---------+-------------------------+------------------+
Total database accesses: 13

Limit the data points in Highchart

I have a following statement and it generates the mentioned output by averaging data within every 20 minutes of range.
Statement :
SELECT record_no, date_time,
ROUND(AVG(UNIX_TIMESTAMP(date_time))) AS time_value,
ROUND(AVG(ph1_active_power),4) AS p1,
ROUND(AVG(ph2_active_power),4) AS p2,
ROUND(AVG(ph3_active_power),4) AS p3
FROM powerpro1
GROUP BY date_time DIV 2000
Portion of the output
+-----------+---------------------+------------+---------+----------+----------+
| record_no | date_time | time_value | p1 | p2 | p3 |
+-----------+---------------------+------------+---------+----------+----------+
| 1 | 2014-12-01 00:00:00 | 1417372770 | 72.6242 | -68.7428 | -72.6242 |
| 21 | 2014-12-01 00:20:00 | 1417373970 | 71.6624 | -69.7448 | -71.6624 |
| 41 | 2014-12-01 00:40:00 | 1417375170 | 70.6869 | -70.7333 | -70.6869 |
| 61 | 2014-12-01 01:00:00 | 1417376370 | 69.6977 | -71.7082 | -69.6977 |
| 81 | 2014-12-01 01:20:00 | 1417377570 | 68.6952 | -72.6692 | -68.6952 |
| 101 | 2014-12-01 01:40:00 | 1417378770 | 67.6794 | -73.6162 | -67.6794 |
| 121 | 2014-12-01 02:00:00 | 1417379970 | 66.6505 | -74.549 | -66.6505 |
| 141 | 2014-12-01 02:20:00 | 1417381200 | 65.5825 | -75.4901 | -65.5825 |
+-----------+---------------------+------------+---------+----------+----------+
According to the no of records in the table named "powerpro1", the above query selects 1368 records when the executing. (May be increased in the future when receiving new records)
My requirement is to create a highchart using time_value for the x-axis and p1, p1 and p3 for the y-axis. But I needs to limit the no of points in the x-axis.
Can anyone like to help me to show this 1368 points by 1000 points in the chart
Unfortunately have no this kind of apporixmation, only in reverse order (I mean datagrouping, if you have 100 points, return i.e 10). So you need to calcualte it on your own and push to your data all 1000 points.

Truth Table For Switching Functions

Can someone explain how these concept works?
I have 1 question. But I don't know have any ideas on constructing the truth table.
f(A,B,C) = AB + A’C
The answer given was ABC + ABC' + A'BC + A'B'C
And i have no idea how it get there. :-(
1. Create a column for each of the inputs, each intermediate functions, and the final function:
A B C | AB | A' | A'C | AB + A'C
--------------------------------
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
2. Enumerate all input possibilities, and start filling in the intermediate function values and then the final function value:
A B C | AB | A' | A'C | AB + A'C
--------------------------------
0 0 0 | 0 | 1 | 0 | 0
0 0 1 | | | |
0 1 0 | | | |
0 1 1 | | | |
1 0 0 | | | |
1 0 1 | | | |
1 1 0 | | | |
1 1 1 | | | |
3. Now, you finish the truth table.
Update per OP's edit of question:
The "answer given" can be reduced as follows using Boolean Algebra:
ABC + ABC' + A'BC + A'B'C
AB(C + C') + A'C(B + B')
AB + A'C
...which is the same as the given f(A,B,C). Not sure why ABC + ABC' + A'BC + A'B'C would be considered to be the "answer," but this does show equivalence between the two formulae.

Resources