Using UNWIND and apoc.coll.shuffle() to randomly select (nodes) & set properties


(Michael McKenzie) #1

I am trying to randomly select / shuffle a group of nodes to set properties. What I currently have does this 19 times, but I just need it done once. This feels like a simple thing I am missing.

UNWIND apoc.coll.shuffle(range(1,19,1)) AS value
MATCH (th:TerrainHex {id: value})
UNWIND [["Fields", "Grain"], 
		["Fields", "Grain"], 
		["Fields", "Grain"], 
		["Fields", "Grain"], 
		["Forest", "Wood"], 
		["Forest", "Wood"], 
		["Forest", "Wood"], 
		["Forest", "Wood"], 
		["Pasture", "Wool"],
		["Pasture", "Wool"], 
		["Pasture", "Wool"], 
		["Pasture", "Wool"], 
		["Mountains", "Ore"], 
		["Mountains", "Ore"], 
		["Mountains", "Ore"], 
		["Hills", "Brick"], 
		["Hills", "Brick"], 
		["Hills", "Brick"], 
		["Desert", "None"]] as hexName
SET th.name = hexName[0], 
	th.resource = hexName[1]

(Christophe Willemsen) #2

Take the first element of the shuffled collection ?

WITH apoc.coll.shuffle(range(1,19,1))[0] AS value
MATCH (th:TerrainHex {id: value})
...

(Michael McKenzie) #3

Unfortunately that only sets the properties of 1 node (likely the last one at value[0]


(Christophe Willemsen) #4

Allright, I think I misunderstood the first time, what about this ?

WITH apoc.coll.shuffle(range(1,19,1)) AS values
MATCH (th:TerrainHex) WHERE th.id IN values
...

(Michael McKenzie) #5

That still runs 19 times. I think it might be due to the second UNWIND (which also has 19 items)


(Andrew Bowman) #6

The missing piece here is using the value as an index into your hexName list. Here's a query which should work for you, though it constructs the hexName list programmatically (ignore that part if you're going to parameterize the list as input to the query)

UNWIND range(1,4) as times
WITH collect(["Fields", "Grain"]) + collect(["Forest", "Wood"]) + collect(["Pasture", "Wool"]) as resources
UNWIND range(1,3) as times
WITH resources + collect(["Mountains", "Ore"]) + collect(["Hills", "Brick"]) + [["Desert", "None"]] as resources
WITH apoc.coll.shuffle(resources) as resources
UNWIND range(1,19) as value
MATCH (th:TerrainHex {id: value})
WITH th, resources[value - 1] as hexName
SET th.name = hexName[0], 
	th.resource = hexName[1]

(Michael McKenzie) #7

That was :fire::fire::fire:

I took what you provided and kept it in a similar format. Below is the working code for reference:

WITH [["Fields", "Grain"], 
      ["Fields", "Grain"], 
      ["Fields", "Grain"], 
      ["Fields", "Grain"], 
      ["Forest", "Wood"], 
      ["Forest", "Wood"], 
      ["Forest", "Wood"], 
      ["Forest", "Wood"], 
      ["Pasture", "Wool"],
      ["Pasture", "Wool"], 
      ["Pasture", "Wool"], 
      ["Pasture", "Wool"], 
      ["Mountains", "Ore"], 
      ["Mountains", "Ore"], 
      ["Mountains", "Ore"], 
      ["Hills", "Brick"], 
      ["Hills", "Brick"], 
      ["Hills", "Brick"], 
      ["Desert", "None"]] AS resources
WITH apoc.coll.shuffle(resources) AS resources
UNWIND range(1,19) AS value
MATCH (th:TerrainHex {id: value})
WITH th, resources[value -1] AS hexName
SET th.name = hexName[0], 
	th.resource = hexName[1]

Thanks!