How to add weight as label to vertex? - cypher

I want to add weight to the vertex.
I have the first step going in r-studio. The following code gives a dataframe with the weight:
query = "
MATCH (p)-[:REFERS_TO]->(q)<-[:REFERS_TO]-(r)
WHERE (ID(p) < ID(q))
RETURN q.name, COUNT(q) AS Weight
ORDER BY Weight DESC
"
newvalue = cypher(graph, query)
How can the weight be added to the vertex as a label? The following does not work for me because it adds the weight to the node instead of the vertex:
query = "
MATCH (p)-[:REFERS_TO]->(q)<-[:REFERS_TO]-(r)
WITH q.name, COUNT(q) AS Weight
SET q.weight = Weight
"
cypher(graph, query)
Thanks!

I think what you're trying to do is to add the weight to the edge (or relationship) rather than to the node (or vertex).
In order to add the weight as a property of the edge, you need to bind it to a variable, and then you can set the property as before:
query = "
MATCH (p)-[r1:REFERS_TO]->(q)<-[r2:REFERS_TO]-(r)
WITH q.name, COUNT(q) AS Weight
SET r1.weight = Weight, r2.weight = Weight
"
cypher(graph, query)
Note I can't tell which of the relationships you want the weight on, so in this example I'm doing both. The only thing here is I'm binding those two relationships to r1 and r2. Relationships can have properties just like nodes, so the rest is straightforward.

Related

Filter neo4j result, return distinct combination of node IDs

I have a graph with Airport nodes and Flight relationships, and I want to find triangles from a specific node where the edges are all within 10% length of each other.
MATCH path = (first:Airport{ID: 12953})-[f1:Flight]->
(second:Airport)-[f2:Flight]->
(third:Airport)-[f3:Flight]->
(last:Airport{ID: 12953})
WHERE second.ID <>first.ID AND
third.ID <>first.ID AND
f1.Distance<=(1.1*f2.Distance) AND
f1.Distance<=(1.1*f3.Distance) AND
f2.Distance<=(1.1*f1.Distance) AND
f2.Distance<=(1.1*f3.Distance) AND
f3.Distance<=(1.1*f1.Distance) AND
f3.Distance<=(1.1*f2.Distance)
WITH (first.ID, second.ID, third.ID) as triplet
return count(DISTINCT triplet)
I only want to return a set of nodes once (no matter how many different flights exist between them), but the with line doesn't work. Basically what I want to create is a new type of variable "object" that has the three IDs as its properties and run distinct on that. Is that possible in neo4j? If not, is there some workaround?
You can use the APOC function apoc.coll.sort to sort each list of 3 IDs, so that the DISTINCT option will properly treat lists with the same IDs as being the same.
Here is a simplified query that uses the APOC function:
MATCH path = (first:Airport{ID: 12953})-[f1:Flight]->
(second:Airport)-[f2:Flight]->
(third:Airport)-[f3:Flight]->
(first)
WHERE second <> first <> third AND
f2.Distance<=(1.1*f1.Distance)>=f3.Distance AND
f1.Distance<=(1.1*f2.Distance)>=f3.Distance AND
f1.Distance<=(1.1*f3.Distance)>=f2.Distance
RETURN COUNT(DISTINCT apoc.coll.sort([first.ID, second.ID, third.ID]]))
NOTE: the second <> first test may not be necessary since there should not be any flights (if a "flight" is the same as a "leg") that fly from an airport back to itself.
You can return an object with keys or an array. For example:
UNWIND range(1, 10000) AS i
WITH
{
id1: toInteger(rand()*3),
id2: toInteger(rand()*3),
id3: toInteger(rand()*3)
} AS triplet
RETURN DISTINCT triplet
or
UNWIND range(1, 10000) AS i
WITH
[ toInteger(rand()*3), toInteger(rand()*3), toInteger(rand()*3) ] AS triplet
RETURN DISTINCT triplet
Update. You can simplify your query by reusing a variable in the query, specifying the length of the path and using the list functions:
MATCH ps = (A:Airport {ID: 12953})-[:Flight*3]->(A)
WITH ps
WHERE reduce(
total = 0,
rel1 IN relationships(ps) |
total + reduce(
acc = 0,
rel2 IN relationships(ps) |
acc + CASE WHEN rel1.Distance <= 1.1 * rel2.Distance THEN 0 ELSE 1 END
)) = 0
RETURN count(DISTINCT [n IN nodes(ps) | n.ID][0..3])

How to sum consecutive rows in Power Query

I have in Power Query a Column "% sum of all". I need to create a custom column "Sum Consecutive" that each row has as value the "% sum of all" of the current row + the value of "Sum Consecutive" of the previous row.
Current row situation
New Custom Column Expectation
You can see two images that show the current situation and the next situation I need in the Power Query.
Can you please help me find a code/command to create this new column like that?
Although there are similar solved questions in DAX, I still need to keep editing the file after that, so it should be performed in M language in power query.
Thank you!
Not sure how performant my approaches are. I would think both should be reasonably efficient as they only loop over each row in the table once (and "remember" the work done in the previous rows). However, maybe the conversion to records/list and then back to table is slow for large tables (I don't know).
Approach 1: Isolate the input column as a list, transform the list by cumulatively adding, put the transformed list back in the table as a new column.
let
someTable = Table.FromColumns({List.Repeat({0.0093}, 7) & List.Repeat({0.0086}, 7) & {0.0068, 0.0068}}, {"% of sum of all"}),
listToLoopOver = someTable[#"% of sum of all"],
cumulativeSum = List.Accumulate(List.Positions(listToLoopOver), {}, (listState, currentIndex) =>
let
numberToAdd = listToLoopOver{currentIndex},
sum = try listState{currentIndex - 1} + numberToAdd otherwise numberToAdd,
append = listState & {sum}
in
append
),
backToTable = Table.FromColumns(Table.ToColumns(someTable) & {cumulativeSum}, Table.ColumnNames(someTable) & {"Cumulative sum"})
in
backToTable
Approach 2: Convert the table to a list of records, loop over each record and add a new field (representing the new column) to each record, then convert the transformed list of records back into a table.
let
someTable = Table.FromColumns({List.Repeat({0.0093}, 7) & List.Repeat({0.0086}, 7) & {0.0068, 0.0068}}, {"% of sum of all"}),
listToLoopOver = Table.ToRecords(someTable),
cumulativeSum = List.Accumulate(List.Positions(listToLoopOver), {}, (listState, currentIndex) =>
let
numberToAdd = Record.Field(listToLoopOver{currentIndex}, "% of sum of all"),
sum = try listState{currentIndex - 1}[Cumulative sum] + numberToAdd otherwise numberToAdd, // 'try' should only be necessary for first item
recordToAdd = listToLoopOver{currentIndex} & [Cumulative sum = sum],
append = listState & {recordToAdd}
in
append
),
backToTable = Table.FromRecords(cumulativeSum)
in
backToTable
I couldn't find a function in the reference for M/Power Query that sums a list cumulatively.

Google Data Studio incorrect calculated metrics

I am creating calculated metrics in Data Studio and I am having trouble with the results.
Metric 1 uses this formula:
COUNT_DISTINCT(CASE WHEN ( Event Category = "ABC" AND Event Action = "XXX" AND Event Label = "123" ) THEN ga clientId (user) ELSE " " END )
[[To count the events with distinct clientIds]]
Metric 2 uses this formula:
COUNT_DISTINCT(CASE WHEN ( Event Category = "ABC" AND Event Action = "YYY" AND Event Label = "456" ) THEN ga clientId (user) ELSE " " END )
[[To count the events with distinct clientIds]]
Metric 3 uses this formula:
COUNT_DISTINCT(CASE WHEN ( Event Category = "ABC" AND Event Action = "ZZZ" AND Event Label = "789" ) THEN userId(user) ELSE " " END )
[[To count the events with distinct userIds]]
The formulas work fine and when I do Metric 2/ Metric 1 the number is correct for a one day time span. When I do Metric 3/Metric 2 the number is wrong. Why is this? It doesn't make sense to me since they are both numerical values.
Also, when I increase the date range the Metric 2 / Metric 1 is incorrect too! Any ideas why these are not working?
If you are aggregating over a certain amount of data, then these calculations will not be exact; they will be approximations.
I have noticed that Google Data Studio is more accurate with data properly loaded into BigQuery rather than data loaded through something else like a PostgreSQL connector. Otherwise, APPROX_COUNT_DISTINCT may be used.

Changing average price in Material Master (MM02) programmatically

I want to programmatically change the moving/average price(s) of materials for the following special case:
VPRSV = 'S' (Standard price)
MLMAA = 'X' (Material Ledger activated)
MLAST = '3' (Material Price Determination = '3' (Single-/Multilevel))
period = current
It has to work when there is already a material document for the given material in the current period. All other special cases that I need are solved.
I am searching for the function module equivalent of changing the moving average price using MM02, not MR21.
Maybe BAPI_MATVAL_PRICE_CHANGE is what I'm searching for?
What confuses me is that I cannot find a parameter that determines that I want to change the moving average price and not the standard price. Did I miss a parameter? If not, does it change the standard price or moving average price?
And I'm not sure whether this function module is the equivalent of MM02 or MR21.
no, there is not such a function module. But you can use Bapi BAPI_MATVAL_PRICE_CHANGE to post price differences to ML. With this you can adjust your price to the value that you want.
You should use BAPI_MATERIAL_SAVEDATA to do this. Several mandatory structures should be filled for the successful update of average price:
HEADDATA-MATERIAL = P_MATNR. "material number
HEADDATA-ACCOUNT_VIEW = 'X'.
VALDATA-VAL_AREA = P_BWKEY. "valuation area
VALDATA-VAL_TYPE = P_BWTAR. "valuation type
VALDATA-MOVING_PR = P_STPRS. "new value of moving price
VALDATAX-VAL_AREA = P_BWKEY. "valuation area for tax accounting
VALDATAX-VAL_TYPE = P_BWTAR. "valuation type for tax accounting
VALDATAX-MOVING_PR = 'X'. "update indicator
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
EXPORTING
HEADDATA = HEADDATA
VALUATIONDATA = VALDATA
VALUATIONDATAX = VALDATAX
IMPORTING
RETURN = BAPI_RETURN
TABLES
MATERIALDESCRIPTION = INT_MAKT
.

Data structure for efficient multi-parameters search

I have collection of multidimensional object (e.g class Person = {age : int , height : int, weight : int etc...}).
I need to query the collection with queries where some dimensions are fixed and the rest unspecified (e.g getallPersonWith {age = c , height = a} or getAllPersonWith {weigth = d}...)
Right now i have a multimap with {age, Height,...} (e.g all dimension that can be fixed) -> List : Person.To perform a query i first compute the set of keys that verify the query, then merge the corresponding list from the map.
Is there anything better, in terms of query speed ? in particular is there anything closer to using one sorted list by dimension (which i believe to be the fastest solutions, but too cumbersome to manage:) )
Just to be clear, i am not looking for an sql query.
For your purpose you can have a look at:
http://code.google.com/p/cqengine/
Should get you in the right direction
You mean something like:
SELECT * FROM person p
WHERE gender = 'F'
AND age >=18
AND age < 30
AND weight > 60 -- metric measures here !!
AND weight < 70
AND NOT EXISTS (
SELECT * from couple c
WHERE c.one = p.id OR c.two=p.id
);
Why do you think I use SQL?