在我的Neo4j / Spring Data Neo4j 4项目中,我有一个实体:Product
每个Product
都有一个Integer
属性 - price
例如,我有以下产品的价格:
Product1.price = 100
Product2.price = 305
Product3.price = 10000
Product4.price = 1000
Product5.price = 220
产品之间没有关联关系。
我需要根据初始价格值(Cypher查询参数)查找通过最大价格增量(Cypher查询参数)彼此不同的产品集(路径)。
例如,我需要找到Neo4j数据库中的所有产品,从price = 50开始,价格delta = 150.作为输出,我希望得到以下产品:
Product1.price = 100
Product5.price = 220
Product2.price = 305
计算如下:
起点价格= 50因此第一个产品的价格应不低于50且不高于200(50 + 150)。所以基于此,我们从我们的目录中找到了一个价格= 100的产品。第二个产品的价格不应低于100且不超过250(100 + 150)..这个产品的价格= 220 ..第三个价格不低于220而不是370.这是一个价格= 305
的产品请您展示一个Cypher查询,它会找到这类产品。
答案 0 :(得分:1)
这在Cypher中执行相当复杂。我遇到的唯一方法是使用REDUCE()函数和CASE语句,有条件地将产品添加到列表末尾,如果它在列表中最后一个产品的价格差值内。
请记住,使用这种方法无法使产品处理短路。如果总产品有100万,并且我们在有序的产品列表中发现只有前两种产品属于该增量模式,则此查询将继续检查这些百万种产品中的每一种产品,尽管它们都不会是添加到我们的列表中。
此查询应该适合您。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
CustomView customView = (CustomView) findViewById(R.id.custom_view);
customView.setImage(R.drawable.some_icon);
customView.setText("Hello world");
}
答案 1 :(得分:1)
解决方案需要在迭代期间传输中间结果。一个有趣的问题,因为今天cypher没有直接提供这种可能性。作为练习(草图),使用modifier中的apoc.periodic.commit
过程 - library:
CALL apoc.create.uuid() YIELD uuid
CALL apoc.periodic.commit("
MERGE (H:tmpVars {id: {tmpId}})
ON CREATE SET H.prices = [],
H.lastPrice = {lastPrice},
H.delta = {delta}
WITH H
MATCH (P:Product) WHERE P.price > H.lastPrice AND
P.price < H.lastPrice + H.delta
WITH H, max(P.price) as lastPrice
SET H.lastPrice = lastPrice,
H.prices = H.prices + lastPrice
RETURN 1
", {tmpId: uuid, delta: 150, lastPrice: 50}
) YIELD updates, executions, runtime
MATCH (T:tmpVars {id: uuid})
WITH T, T.prices as prices DETACH DELETE T
WITH prices
UNWIND prices as price
MATCH (P:Product) WHERE P.price = price
RETURN P ORDER BY P.price ASC
答案 2 :(得分:1)
作为一种替代解决方案,其查询速度应该更快,但需要更多维护和保养以保持正常工作(特别是在快速变化的产品价格数据时),您可以按升序价格顺序在产品节点之间创建关系,并保持将三角洲作为关系属性。
以下是使用APOC程序创建此内容的方法:
MATCH (p:Product)
WITH p
ORDER BY p.price ASC
WITH apoc.coll.pairsMin(COLLECT(p)) as products
UNWIND products as prodPairs
WITH prodPairs[0] as prod1, prodPairs[1] as prod2
CREATE (prod1)-[r:NextProd]->(prod2)
SET r.delta = prod2.price - prod1.price
以下是设置后的问题。
WITH {startPrice:50, delta:150} as params
WITH params, params.startPrice + params.delta as ceiling
MATCH (start:Product)
WHERE params.startPrice <= start.price <= ceiling
WITH start, params
ORDER BY start.price ASC
LIMIT 1
MATCH (start)-[r:NextProd*0..]->(product:Product)
WHERE ALL(rel in r WHERE rel.delta <= params.delta)
RETURN DISTINCT product
这应该是一个相当快的查询,因为当ALL()谓词达到超过所需增量的关系时,它应该切断变量匹配。
当然,缺点是您需要确保每个影响此链表结构的操作(添加或删除产品和更改产品价格)都能正确调整结构,您可能需要考虑锁定方法确保线程安全,以便在产品和/或价格同时更新时不会破坏链表。