# If neo4j official not available, use web archive:
# http://web.archive.org/web/20240729075918id_/http://dist.neo4j.org/neo4j-community-5.22.0-windows.zip
# or latest version which may not be compatible with video:
# http://web.archive.org/web/20250425091340id_/http://dist.neo4j.org/neo4j-community-5.26.0-windows.zip
$url = 'http://dist.neo4j.org/neo4j-community-5.22.0-windows.zip'
$name = ($url -split '/')[-1]
# Download:
Invoke-RestMethod $url -OutFile "~\Downloads\$name"
# Extract:
Expand-Archive "~\Downloads\$name" "~\AppData\Local\Programs"
# Add to PATH, i.e.:
$env:Path += "C:\Users\user\AppData\Local\Programs\neo4j-community-5.22.0\bin;"
# Set initial password:
neo4j-admin dbms set-initial-password qwertyuiop
# ? Set-ExecutionPolicy RemoteSigned
# Done. Now if you'll start this server, you can connect to it with neo4j/qwertyuiop
CREATE (m1:Movie {id: 1, title: 'The Matrix', release_year: 1999}),
(m2:Movie {id: 2, title: "The Devil's Advocate", release_year: 1997}),
(m3:Movie {id: 3, title: 'The Godfather', release_year: 1972}),
(m4:Movie {id: 4, title: 'John Wick', release_year: 2014});
UNWIND [
{
id: 1,
name: "Keanu Reeves",
birthYear: 1964
},
{
id: 2,
name: "Al Pacino",
birthYear: 1940
},
{
id: 3,
name: "Hugo Weaving",
birthYear: 1960
}
] AS node
CREATE (n:Person) SET n = node;
UNWIND [
[1, 1],
[3, 1],
[1, 2],
[2, 2],
[2, 3],
[1, 4]
] AS pair
MATCH (p:Person {id: pair[0]}), (m:Movie {id: pair[1]})
CREATE (p)-[:ACTED_IN]->(m);
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
RETURN p.name, COLLECT(m.title) AS movies
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
RETURN p.name, COLLECT(m.title)[..4] AS movies
LIMIT 10
Get-Clipboard | cypher-shell -u neo4j -p qwertyuiop
Get-Clipboard | cypher-shell -u neo4j -p qwertyuiop --format verbose
@'
:params {blabla: 'Al.*'}
MATCH (n:Person) WHERE n.name =~ $blabla RETURN id(n),n.name;
'@ | cypher-shell.bat -u neo4j -p qwertyuiop
@'
MATCH (n:Person) WHERE n.name =~ $blabla RETURN id(n),n.name;
'@ | cypher-shell.bat -u neo4j -p qwertyuiop -P "{blabla: 'Al.*'}"
'RETURN $blabla' | cypher-shell.bat -u neo4j -p qwertyuiop -P "{blabla: time()}"
$env:JAVA_TOOL_OPTIONS = '-Dstdout.encoding=UTF-8'
[Console]::InputEncoding = [console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
'RETURN "ЖУЖЕЛИЦА ⨌ 🤡" AS x;' | cypher-shell.bat -u neo4j -p qwertyuiop
function Invoke-CypherNeo4j ($cypher, $params) {
if ($null -eq $cred) {$Global:cred = Get-Credential}
$bodyJson = $bodyJson = @{ statements=@( @{statement=$cypher} ) } | ConvertTo-Json -d 99
if ($params) {
$bodyJson = @{ statements=@( @{statement=$cypher; parameters=$params}) } | ConvertTo-Json -d 99
}
$resp = Invoke-RestMethod http://localhost:7474/db/neo4j/tx/commit -Method Post -ContentType 'application/json' -Body $bodyJson -Credential $cred -AllowUnencryptedAuthentication
if ($resp.errors.Count -ne 0) {return $resp.errors}
else {
$resp.results.data | % {
$obj = [ordered]@{}
for ($i = 0; $i -lt $_.row.count; $i++) {
$key = ([array]($resp.results.columns)).get($i)
$value = $_.row[$i]
$obj[$key] = $value
}
[pscustomobject]$obj
}
}
}
{
"statements": [
{
"statement": "MATCH (p:Person)-[:ACTED_IN]->(m:Movie)\r\nWHERE p.name STARTS WITH 'H'\r\nRETURN p.name, COLLECT(m.title) AS movies"
}
]
}
{
"statements": [
{
"statement": "UNWIND $coolguys as guy CREATE (p:Person) SET p = guy RETURN p",
"parameters": {
"coolguys": [
{
"name": "Vasya",
"age": 69
},
{
"name": "Petya",
"age": 33
},
{
"name": "Kolya",
"age": 55
}
]
}
}
]
}
{
"statements": [
{
"statement": "RETURN 2/0"
},
{
"statement": "MATCH (n) DETACH DELETE n"
}
]
}
{
"statements": [
{
"statement": "RETURN 100/$x",
"parameters": {
"x": 5
}
},
{
"statement": "MATCH (n) WHERE n.name STARTS WITH $suffix AND n.born < $num RETURN n",
"parameters": {
"suffix": "A",
"num": 1961
}
}
]
}
curl -X POST -H 'Content-type: application/json' http://neo4j:qwertyuiop@localhost:7474/db/neo4j/tx/commit -d $bodyJson
$cred = Get-Credential
Invoke-WebRequest http://localhost:7474/db/neo4j/tx/commit -Method Post -ContentType 'application/json' -Body $bodyJson -Credential $cred -AllowUnencryptedAuthentication | % Content
Query API was first released with Neo4j 5.19.
function Invoke-CypherNeo4j {
[CmdletBinding()]
param(
[string]$Cypher,
[HashTable]$Params,
[switch]$Raw
)
if ($null -eq $neo4jCred) {$Global:neo4jCred = Get-Credential}
$neo4jUrl = 'http://localhost:7474/db/neo4j/query/v2'
$body = @{ statement=$Cypher; parameters=$Params } | ConvertTo-Json -d 9 -Compress
$respIwr = Invoke-WebRequest -Uri $neo4jUrl -Method Post `
-ContentType 'application/json' `
-Credential $neo4jCred `
-AllowUnencryptedAuthentication `
-Body $body `
-SkipHttpErrorCheck
if ($Raw) { return $respIwr.Content }
$resp = $respIwr.content | ConvertFrom-Json -d 9
if ($resp.errors.Count -ne 0) { return $respIwr.Content }
for ($i = 0; $i -lt $resp.data.values.count; $i++) {
$obj = [ordered]@{}
$row = ([array]($resp.data.values)).get($i)
for ($j = 0; $j -lt $resp.data.fields.count; $j++) {
$key = ([array]($resp.data.fields)).get($j)
$value = $row.get($j)
$obj[$key] = $value
}
[pscustomobject]$obj
}
}
function Invoke-Sparql ($sparql) {
$sparql = $sparql -join "`r`n"
$wdurl = 'https://query.wikidata.org/sparql'
#curl --silent -X POST -H 'Content-type: application/sparql-query' -H 'Accept: text/csv' -d $sparql $wdurl | ConvertFrom-Csv
# or
Invoke-RestMethod -Uri $wdUrl -Method Post -Body @{query=$sparql} -Headers @{"Accept" = "text/csv"} | ConvertFrom-Csv
}
# create people csv
$sparql = @'
SELECT ?el ?elLabel (SAMPLE(YEAR(?birthdate)) AS ?byear) (SAMPLE(YEAR(?deathdate)) AS ?dyear) ?links
WHERE {
wd:Q130734 wdt:P40* ?el .
OPTIONAL {
?el p:P569 ?pb .
?pb psv:P569 [
wikibase:timeValue ?birthdate;
wikibase:timePrecision ?precisionb ;
];
FILTER ( xsd:integer(?precisionb) >= 9 )
}
OPTIONAL {
?el p:P570 ?pd .
?pd psv:P570 [
wikibase:timeValue ?deathdate;
wikibase:timePrecision ?precisiond ;
];
FILTER ( xsd:integer(?precisiond) >= 9 )
}
OPTIONAL {?el wikibase:sitelinks ?links }
SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,[AUTO_LANGUAGE],en". }
} GROUP BY ?el ?elLabel ?links
'@
Invoke-Sparql $sparql | ConvertTo-Csv > delmePpl.csv
# create haschild rels csv
$sparql = @'
# Ancestry table
SELECT DISTINCT ?parent ?child WHERE {
wd:Q130734 wdt:P40* ?parent .
?parent wdt:P40 ?child .
MINUS {
?otherParent wdt:P40 ?child .
FILTER (?otherParent != ?parent)
}
}
'@
Invoke-Sparql $sparql | ConvertTo-Json > delmeRels.json
#create places csv
$sparql = @'
SELECT DISTINCT ?el ?place ?point ?lat ?long ?placeLabel WHERE {
{ wd:Q130734 wdt:P40* ?el .}
UNION {
wd:Q130734 wdt:P40* ?el .
}
?el wdt:P19 ?place .
?place wdt:P625 ?point ;
p:P625 ?coordinate.
?coordinate psv:P625 [
wikibase:geoLatitude ?lat;
wikibase:geoLongitude ?long
] .
SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en". }
}
'@
Invoke-Sparql $sparql | ConvertTo-Csv > delmePlaces.csv
#import people from csv
$2dArray = Import-Csv delmePpl.csv | % {,($_.psobject.properties.value)}
$cypher = @'
UNWIND $rows as row
CREATE (p:Person {qid: row[0], name: row[1], birth: toInteger(row[2]), death: toInteger(row[3]), links: toInteger(row[4])});
'@
Invoke-CypherNeo4j $cypher -params @{rows = $2dArray}
#import rels from json
$rels = cat .\delmeRels.json | ConvertFrom-Json
$cypher = @'
UNWIND $objs as obj
MATCH (p1:Person {qid: obj.parent}), (p2:Person {qid: obj.child})
CREATE (p1)-[:HAS_CHILD]->(p2);
'@
Invoke-CypherNeo4j $cypher -params @{objs = $rels}
#import places from csv
$places = Import-Csv delmePlaces.csv
$cypher = @'
UNWIND $objs AS obj
MATCH (n:Person {qid: obj.el})
MERGE (x:Place {
qid: obj.place,
name: obj.placeLabel,
location: point({longitude: toFloat(obj.long), latitude: toFloat(obj.lat)})
})
CREATE (n)-[:BORN_IN]->(x);
'@
Invoke-CypherNeo4j $cypher -params @{objs = $places}
MATCH (n:Person) -[r:BORN_IN]-> (pl:Place)
RETURN pl.name,count(n),collect(n);
MATCH p = shortestPath(
(p1:Person {name: 'Николай I'})-[:HAS_CHILD*]-(p2:Person {qid: 'http://www.wikidata.org/entity/Q43274'})
)
UNWIND nodes(p) AS node
MATCH (node)-[r:HAS_CHILD]->(child)
RETURN node, COLLECT(child) AS children, r
MATCH p = shortestPath(
(p1:Person {name: 'Николай I'})-[:HAS_CHILD*]-(p2:Person {name: 'Николай II'})
)
UNWIND nodes(p) AS node
MATCH (node)-[:HAS_CHILD]->(child)
RETURN node, COLLECT(child) AS children
MATCH p = shortestPath(
(p1:Person {name: 'Николай I'})-[rels:HAS_CHILD*]-(p2:Person {name: 'Николай II'})
)
UNWIND rels AS rel
WITH startNode(rel) AS from, endNode(rel) AS to
MERGE (from) -[:HAS_CHILD_TMP]-> (to);
SELECT ?el ?elLabel (SAMPLE(YEAR(?birthdate)) AS ?byear) (SAMPLE(YEAR(?deathdate)) AS ?dyear) ?links
WHERE {
wd:Q130734 wdt:P40* ?el .
OPTIONAL {
?el p:P569 ?pb .
?pb psv:P569 [
wikibase:timeValue ?birthdate;
wikibase:timePrecision ?precisionb ;
];
FILTER ( xsd:integer(?precisionb) >= 9 )
}
OPTIONAL {
?el p:P570 ?pd .
?pd psv:P570 [
wikibase:timeValue ?deathdate;
wikibase:timePrecision ?precisiond ;
];
FILTER ( xsd:integer(?precisiond) >= 9 )
}
OPTIONAL {?el wikibase:sitelinks ?links }
SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,[AUTO_LANGUAGE],en". }
} GROUP BY ?el ?elLabel ?links
$sparql = gcb -Raw
curl -X POST -H 'Content-Type: application/sparql-query' -H 'Accept: text/csv' --data $sparql https://query.wikidata.org/sparql -o delme.csv
where.exe neo4j
@'
LOAD CSV WITH HEADERS FROM 'file:///delme.csv' AS node
CREATE (p:Person) SET p = node;
'@ | cypher-shell.bat -u neo4j -p qwertyuiop
$neo4jHome = where.exe neo4j.bat | gi | % Directory | % Parent | % FullName
cd $neo4jHome
copy .\labs\apoc* .\plugins\
'apoc.export.file.enabled=true' > .\conf\apoc.conf
neo4j console
CALL apoc.export.cypher.all(null,{stream:true});
CALL apoc.export.cypher.all(null,{stream:true}) YIELD cypherStatements RETURN cypherStatements;
CALL apoc.export.cypher.all('delmeAll.cypher');
# Install node.js:
# https://nodejs.org/en/download/prebuilt-binaries
$url = 'https://nodejs.org/dist/v20.16.0/node-v20.16.0-win-x64.zip'
$name = ($url -split '/')[-1]
irm $url -OutFile "~\Downloads\$name"
Expand-Archive ~/downloads/$name $env:LOCALAPPDATA/Programs
$env:PATH += "C:\Users\user\AppData\Local\Programs\node-v20.16.0-win-x64\;"
corepack enable
cd $env:LOCALAPPDATA/Programs
git clone --depth 1 https://github.com/neo4j-labs/neodash
cd neodash
yarn install
# run:
yarn run dev
MATCH (p:Person)
WHERE p.birth IS NOT NULL AND p.death IS NOT NULL
WITH p.birth / 10 * 10 as decadeOfBirth, avg(p.death - p.birth) as yearsLived, COUNT(p) AS peopleBorn
RETURN decadeOfBirth, yearsLived, peopleBorn
ORDER BY decadeOfBirth
MATCH p = (n:Person) -[:HAS_CHILD]-> ()
WHERE n.name = $neodash_person_name
RETURN p;
irm 'https://repo1.maven.org/maven2/org/neo4j/client/neo4j-browser/5.21.0/neo4j-browser-5.21.0.jar' -OutFile C:\Users\user\Downloads\neo4j-browser-5.21.0.jar
Expand-Archive C:\Users\user\Downloads\neo4j-browser-5.21.0.jar '.\neo4j-browser-5.21.0\'
python -m http.server --directory .\browser\ 7474