아주 좋은 질문입니다. 나는 아직 전체 해결책을 가지고 있지 않지만, Martin Preusse가 말했듯이 우리는 데카르트 제품을 만들려고합니다.
이 어렵지만, 당신은 해킹 사용을 포함하여 많은하여 해결할 수 있습니다 이중 감소 :
WITH [['a', 'b'], [1, 2, 3], [true, false]] AS hs
WITH hs, size(hs) AS numberOfHobbys, reduce(acc = 1, h in hs | acc * size(h)) AS numberOfCombinations, extract(h IN hs | length(h)) AS hLengths
WITH hs, hLengths, numberOfHobbys, range(0, numberOfCombinations-1) AS combinationIndexes
UNWIND combinationIndexes AS combinationIndex
WITH
combinationIndex,
reduce(acc = [], i in range(0, numberOfHobbys-1) |
acc + toInt(combinationIndex/(reduce(acc2 = 1, j in range(0, i-1) | acc2 * hLengths[j]))) % hLengths[i]
) AS indices,
reduce(acc = [], i in range(0, numberOfHobbys-1) |
acc + reduce(acc2 = 1, j in range(0, i-1) | acc2 * hLengths[j])
) AS multipliers,
reduce(acc = [], i in range(0, numberOfHobbys-1) |
acc + hs[i][
toInt(combinationIndex/(reduce(acc2 = 1, j in range(0, i-1) | acc2 * hLengths[j]))) % hLengths[i]
]
) AS combinations
RETURN combinationIndex, indices, multipliers, combinations
을 아이디어는 다음과 같다 : 우리는 잠재적 인 값의 수를 곱하면, 예를 들어, ['a', 'b'], [1, 2, 3], [true, false]
에 대해 쿼리에서 첫 번째 reduce
을 사용하여 n = 2×3×2 = 12
을 계산합니다. 그런 다음 0에서 n-1까지 반복하고 수식 a×1 + b×2 + c×6
을 사용하여 행을 할당합니다. 여기서 a, b, c는 각각 값을 색인하므로 모두 음수가 아닌 정수이고 a < 2
, b < 3
및 c < 2
입니다.
0×1 + 0×2 + 0×6 = 0
1×1 + 0×2 + 0×6 = 1
0×1 + 1×2 + 0×6 = 2
1×1 + 1×2 + 0×6 = 3
0×1 + 2×2 + 0×6 = 4
1×1 + 2×2 + 0×6 = 5
0×1 + 0×2 + 1×6 = 6
1×1 + 0×2 + 1×6 = 7
0×1 + 1×2 + 1×6 = 8
1×1 + 1×2 + 1×6 = 9
0×1 + 2×2 + 1×6 = 10
1×1 + 2×2 + 1×6 = 11
결과는 다음과 같습니다
╒════════════════╤═════════╤═══════════╤═════════════╕
│combinationIndex│indices │multipliers│combinations │
╞════════════════╪═════════╪═══════════╪═════════════╡
│0 │[0, 0, 0]│[1, 2, 6] │[a, 1, true] │
├────────────────┼─────────┼───────────┼─────────────┤
│1 │[1, 0, 0]│[1, 2, 6] │[b, 1, true] │
├────────────────┼─────────┼───────────┼─────────────┤
│2 │[0, 1, 0]│[1, 2, 6] │[a, 2, true] │
├────────────────┼─────────┼───────────┼─────────────┤
│3 │[1, 1, 0]│[1, 2, 6] │[b, 2, true] │
├────────────────┼─────────┼───────────┼─────────────┤
│4 │[0, 2, 0]│[1, 2, 6] │[a, 3, true] │
├────────────────┼─────────┼───────────┼─────────────┤
│5 │[1, 2, 0]│[1, 2, 6] │[b, 3, true] │
├────────────────┼─────────┼───────────┼─────────────┤
│6 │[0, 0, 1]│[1, 2, 6] │[a, 1, false]│
├────────────────┼─────────┼───────────┼─────────────┤
│7 │[1, 0, 1]│[1, 2, 6] │[b, 1, false]│
├────────────────┼─────────┼───────────┼─────────────┤
│8 │[0, 1, 1]│[1, 2, 6] │[a, 2, false]│
├────────────────┼─────────┼───────────┼─────────────┤
│9 │[1, 1, 1]│[1, 2, 6] │[b, 2, false]│
├────────────────┼─────────┼───────────┼─────────────┤
│10 │[0, 2, 1]│[1, 2, 6] │[a, 3, false]│
├────────────────┼─────────┼───────────┼─────────────┤
│11 │[1, 2, 1]│[1, 2, 6] │[b, 3, false]│
└────────────────┴─────────┴───────────┴─────────────┘
그래서, 당신의 문제에 대한 쿼리는 다음과 같습니다
╒════════════════════════════════════╕
│combinations │
╞════════════════════════════════════╡
│[Diner, Lounge, Lake] │
├────────────────────────────────────┤
│[Daves BarGrill, Lounge, Lake] │
├────────────────────────────────────┤
│[Diner, Dive Bar, Lake] │
├────────────────────────────────────┤
│[Daves BarGrill, Dive Bar, Lake] │
├────────────────────────────────────┤
│[Diner, Lounge, Mountain] │
├────────────────────────────────────┤
│[Daves BarGrill, Lounge, Mountain] │
├────────────────────────────────────┤
│[Diner, Dive Bar, Mountain] │
├────────────────────────────────────┤
│[Daves BarGrill, Dive Bar, Mountain]│
└────────────────────────────────────┘
:
MATCH (p:Person)-[:likes]->(h:Hobby)-[:canDoAt]->(pl:Place)
WITH p, h, collect(pl.name) AS places
WITH p, collect(places) AS hs
WITH hs, size(hs) AS numberOfHobbys, reduce(acc = 1, h in hs | acc * size(h)) AS numberOfCombinations, extract(h IN hs | length(h)) AS hLengths
WITH hs, hLengths, numberOfHobbys, range(0, numberOfCombinations-1) AS combinationIndexes
UNWIND combinationIndexes AS combinationIndex
WITH
reduce(acc = [], i in range(0, numberOfHobbys-1) |
acc + hs[i][
toInt(combinationIndex/(reduce(acc2 = 1, j in range(0, i-1) | acc2 * hLengths[j]))) % hLengths[i]
]
) AS combinations
RETURN combinations
이는 다음과 같습니다 분명히, 우리는 또한 perso을 얻고 싶습니다. n 및 그/그녀의 취미의 이름 :
MATCH (p:Person)-[:likes]->(h:Hobby)-[:canDoAt]->(pl:Place)
WITH p, h, collect([h.name, pl.name]) AS places
WITH p, collect(places) AS hs
WITH p, hs, size(hs) AS numberOfHobbys, reduce(acc = 1, h in hs | acc * size(h)) AS numberOfCombinations, extract(h IN hs | length(h)) AS hLengths
WITH p, hs, hLengths, numberOfHobbys, range(0, numberOfCombinations-1) AS combinationIndexes
UNWIND combinationIndexes AS combinationIndex
WITH
p, reduce(acc = [], i in range(0, numberOfHobbys-1) |
acc + [hs[i][
toInt(combinationIndex/(reduce(acc2 = 1, j in range(0, i-1) | acc2 * hLengths[j]))) % hLengths[i]
]]
) AS combinations
RETURN p, combinations
결과 :
╒═══════════╤════════════════════════════════════════════════════════════╕
│p │combinations │
╞═══════════╪════════════════════════════════════════════════════════════╡
│{name: Joe}│[[eat, Diner], [drink, Lounge], [hike, Lake]] │
├───────────┼────────────────────────────────────────────────────────────┤
│{name: Joe}│[[eat, Daves BarGrill], [drink, Lounge], [hike, Lake]] │
├───────────┼────────────────────────────────────────────────────────────┤
│{name: Joe}│[[eat, Diner], [drink, Dive Bar], [hike, Lake]] │
├───────────┼────────────────────────────────────────────────────────────┤
│{name: Joe}│[[eat, Daves BarGrill], [drink, Dive Bar], [hike, Lake]] │
├───────────┼────────────────────────────────────────────────────────────┤
│{name: Joe}│[[eat, Diner], [drink, Lounge], [hike, Mountain]] │
├───────────┼────────────────────────────────────────────────────────────┤
│{name: Joe}│[[eat, Daves BarGrill], [drink, Lounge], [hike, Mountain]] │
├───────────┼────────────────────────────────────────────────────────────┤
│{name: Joe}│[[eat, Diner], [drink, Dive Bar], [hike, Mountain]] │
├───────────┼────────────────────────────────────────────────────────────┤
│{name: Joe}│[[eat, Daves BarGrill], [drink, Dive Bar], [hike, Mountain]]│
└───────────┴────────────────────────────────────────────────────────────┘
내가 그렇게 의견을 환영합니다,이 지나친 될 수 있습니다.
중요 사항 : 순수한 Cypher를 사용하면이 작업이 매우 복잡하다는 사실을 클라이언트 응용 프로그램에서 계산하는 것이 좋습니다.
멋지게 생각한 해결책을 받아들입니다. 예, person, hobbie, list (place)를 나열하고 나머지를 Cilent 응용 프로그램에 나열하는 간단한 쿼리를 작성하는 것이 더 적합 할 수도 있습니다 – Azeli
당신은 이것을 생각하지는 않지만 여전히 인상적입니다;) –