@jexp jexp released this Feb 23, 2018 · 12 commits to 3.2 since this release

Assets 3

Happy to announce the release of APOC

APOC wouldn't be there where it is today with countless people contributing, reporting ideas and issues and everyone liking it telling their friends. Please do the same.

I also added a code of conduct and contribution guidelines to APOC, so every contributor feels welcome and safe and also quickly knows how to join our efforts.

For this release again, our friends at Larus Italy, did a lot of the work, besides many bugfixes Angelo Busato also added S3 URL support, which is really cool.

Andrea Santurbano worked on the HDFS support (read / write)

Andrew Bowman worked on a number of improvements around Path expanders

  • added support for sequences of labels and rel-types to express more complex paths
  • support for known end nodes
  • support for compound labels

I also found some time to code and added a bunch of things :)

Aggregation functions (something I wanted to add for a long time)

  • more efficient variants of collect(x)[a..b]
  • apoc.agg.nth, apoc.agg.first, apoc.agg.last, apoc.agg.slice
  • apoc.agg.median(x)
  • apoc.agg.percentiles(x,[0.5,0.9])
  • apoc.agg.product(x)
  • apoc.agg.statistics() provides a full numeric statistic


Implemented an idea of my colleague Ryan Boyd to allow indexing of full "documents", i.e. map-structures per node or relationship that can also contain information from the neighborhood or computed data. Later those can be searched as keys and values of the indexed data.

  • apoc.index.addNodeMap(node, {map})
  • apoc.index.addRelationshipMap(node, {map})

As part of that work, I also wanted to add support for deconstructing complex values or structs.
apoc.map.values to select the values of a subset of keys into a mixed type list
apoc.coll.elements is used to deconstruct a sublist into typed variables (this can also be done with WITH, but requires an extra declaration of the list to be concise)

Path Functions (from a request in neo4j.com/slack)

  • apoc.path.create(startNode, [rels])
  • apoc.path.slice(path, offset, length)
  • apoc.path.combine(path1, path2)

Text functions

  • apoc.text.code(codepoint), apoc.text.hexCharAt(), apoc.text.charAt() (thanks Andrew Bowman)
  • apoc.text.toCypher(value, {}) for generating valid cypher representations of nodes, relationships, paths, values
  • Sørensen–Dice similarity (thanks Florent Biville)
  • Roman <-> arabic conversions (thanks Marcin Cylke)
  • new email and domain extraction functions (thanks David)
  • apoc.text.bytes/apoc.text.byteCount

Data Integration

  • generic XML import with apoc.import.xml() (thanks Stefan Armbruster)
  • pass Cypher parameters to apoc.export.csv.query
  • mongodb integration Added paging parameter in the get and find procedure (Thanks Gleb Belokrys)
  • stream apoc.export.cypher script export back to client when no file-name is given
  • apoc.load.csv
  • handling of converted null values/null columns
  • explicit "nullValues" option to define values that will be replaced by null (global and per field)
  • explicit "results" option to determine which output columns are provided

Collection Functions

  • apoc.coll.combinations(), apoc.coll.frequencies() (Thanks Andrew)
  • update/remove/insert value at collection index (Thanks Brad Nussbaum)

Graph Refactoring

  • per property configurable merge strategy for mergeNodes
  • means to skip properties for cloneNodes

Other Additions

  • added apoc.date.field UDF

Bugfixes around:

  • apoc.load.jdbc (type conversion, connection handling, logging)
  • apoc.refactor.mergeNodes
  • apoc.cypher.run*
  • apoc.schema.properties.distinctCount
  • composite indexes in Cypher export
  • ElasticSearch integration for ES 6
  • Made larger parts of apoc not needing the unrestricted configuration
  • apoc.json.toTree (also config for relationship-name casing)
  • Warmup Improvements (dynamic properties, rel-group)
  • Compound index using apoc.schema.assert (thanks Chris Skardon)
  • Explicit Index Reads don't require read-write-user
  • Enable parsing of lists in GraphML Import (thanks Alex Wilson)
  • Change CYPHER_SHELL format from upper case to lower case. (:begin,:commit)
  • Allowed apoc.node.degree() to use untyped directions (thanks Andrew)