Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      CodeSOD: A Unique Way to Primary Key

      July 22, 2025

      BrowserStack launches Figma plugin for detecting accessibility issues in design phase

      July 22, 2025

      Parasoft brings agentic AI to service virtualization in latest release

      July 22, 2025

      Node.js vs. Python for Backend: 7 Reasons C-Level Leaders Choose Node.js Talent

      July 21, 2025

      The best CRM software with email marketing in 2025: Expert tested and reviewed

      July 22, 2025

      This multi-port car charger can power 4 gadgets at once – and it’s surprisingly cheap

      July 22, 2025

      I’m a wearables editor and here are the 7 Pixel Watch 4 rumors I’m most curious about

      July 22, 2025

      8 ways I quickly leveled up my Linux skills – and you can too

      July 22, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      The Intersection of Agile and Accessibility – A Series on Designing for Everyone

      July 22, 2025
      Recent

      The Intersection of Agile and Accessibility – A Series on Designing for Everyone

      July 22, 2025

      Zero Trust & Cybersecurity Mesh: Your Org’s Survival Guide

      July 22, 2025

      Execute Ping Commands and Get Back Structured Data in PHP

      July 22, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      A Tomb Raider composer has been jailed — His legacy overshadowed by $75k+ in loan fraud

      July 22, 2025
      Recent

      A Tomb Raider composer has been jailed — His legacy overshadowed by $75k+ in loan fraud

      July 22, 2025

      “I don’t think I changed his mind” — NVIDIA CEO comments on H20 AI GPU sales resuming in China following a meeting with President Trump

      July 22, 2025

      Galaxy Z Fold 7 review: Six years later — Samsung finally cracks the foldable code

      July 22, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»Databases»Explore the new openCypher custom functions and subquery support in Amazon Neptune

    Explore the new openCypher custom functions and subquery support in Amazon Neptune

    May 23, 2025

    In this post, we describe some of the openCypher features that have been released as part of the 1.4.2.0 engine update to Amazon Neptune. Neptune is a fast, reliable, and fully managed graph database service for building and running applications with highly connected datasets, such as knowledge graphs, fraud graphs, identity graphs, and security graphs. Neptune provides developers with the choice of building their graph applications using three open graph query languages: openCypher, Apache TinkerPop Gremlin, and the World Wide Web Consortium’s (W3C) SPARQL 1.1. Neptune announced the general availability of the latest engine release to 1.4.2.0 on December 19, 2024. Starting with this release, you can benefit from a variety of new features and improvements, including custom functions and support for the CALL subquery, which we further discuss in this post. You can use the guide at the end of this post to try out the new features that are described.

    Support for read-only CALL subqueries

    For queries that require sub-query support, such as executing a specific openCypher query on a node-by-node basis, support for the CALL function was added. Prior to this, if you wanted to execute additional MATCH statements against a collection of data, it was necessary to split the code into multiple queries, passing the output of one query as the input to the next.

    The following is an example of using the CALL functionality to run a second query that will be run for each result in stopover. The initial MATCH starts at the Austin Bergstrom International (AUS) airport and performs a single-hop traversal across the route edge to a connected stopover node. For each stopover, it then retrieves the first two airports connected to the stopover, ordered by the route distance property value in descending order.

    MATCH (origin:airport {code:"AUS"})-[:route]->(stopover) 
    CALL { 
      WITH stopover 
      MATCH (stopover)-[r:route]->(destination) 
      RETURN destination 
      ORDER BY r.dist DESC LIMIT 2 
    } 
    RETURN origin.desc, stopover.desc, destination.desc

    Prior to support for CALL, the preceding query would not have been possible in openCypher, because Neptune didn’t support functionality to run a subquery on a per-object basis. For more information on how the CALL subquery works, how to write queries using it, and current limitations, see CALL subquery support in Neptune.

    Support for Neptune openCypher custom functions

    Neptune openCypher functions are additions to the Neptune openCypher specification implementation that support customer requirements such as string matching, and collection and map sorting. The following functions are available in Neptune Database version 1.4.2.0 and above, as well as Amazon Neptune Analytics.

    textIndexOf(text :: STRING, lookup :: STRING, from = 0 :: INTEGER?, to = -1 :: INTEGER?) :: (INTEGER?)

    This function returns the index of the first occurrence of lookup in the range of text starting at offset from (inclusive), through offset to (exclusive). If to is -1, the range continues to the end of text. Indexing is zero-based and is expressed in Unicode scalar values (non-surrogate code points). In the following example, we search for a specific expression ‘e’ in the value ‘Amazon Neptune’:

    RETURN textIndexOf('Amazon Neptune', 'e') as result
    {
     "results": [{
      "result": 8
     }]
    }

    collToSet(values :: LIST OF ANY?) :: (LIST? OF ANY?)

    If you wanted to return a list containing only a unique set of values, you would need to combine COLLECT with DISTINCT to produce the results. For example, the following query produces a unique collection of names of airports that have connecting routes to airports located in the US:

    MATCH (:airport {country: 'US'})-[:route]->(d:airport)
    WITH COLLECT(d.desc) AS locations
    RETURN collToSet(locations)

    collSubtract(first :: LIST OF ANY?, second :: LIST OF ANY?) :: (LIST? OF ANY?)

    If you want to return a list that contains only values that are present in one list and not another, you can use the collSubtract function. This function returns a new list containing all the unique elements from the first list, excluding elements from the second list. The order of the list is maintained. For example, the following query produces a unique collection of names of airports in the US that have connecting routes to airports located in France, but don’t also connect to airports in the UK:

    MATCH (:airport {country: 'FR'})-[:route]→(d1:airport {country: 'US'})
    MATCH (:airport {country: 'UK'})-[:route]→(d2:airport {country: 'US'})
    WITH COLLECT(d1.desc) AS FR_Routes, COLLECT(d2.desc) AS UK_Routes
    RETURN collSubtract(FR_Routes,UK_Routes)
    {
      "results": [
        {
          "Routes": [
            "Cincinnati Northern Kentucky International Airport",
            "Indianapolis International Airport"
          ]
        }
      ]
    }

    collIntersection(first :: LIST? OF ANY?, second :: LIST? OF ANY?) :: (LIST? OF ANY?)

    If you want to return a list that contains only the items that exist in two given lists, you can use collIntersection. This function returns a new unique list of items that are present in both of the given parameter lists. For example, the following query produces a unique collection of airport names that have routes originating from either London Heathrow (LHR) or Seattle-Tacoma International (SEA) airport:

    MATCH (lhr:airport {code: 'LHR'})-[:route]->(d1)
    MATCH (sea:airport {code: 'SEA'})-[:route]->(d2)
    WITH collIntersection(COLLECT(d1.desc),COLLECT(d2.desc)) as airports_list
    UNWIND airports_list as airports
    RETURN airports

    Sorting functions

    Neptune sorting functions focus on improving readability and providing flexibility for use cases that involve sorting over complex data types such as single or multiple maps, as well as providing single or multiple sort keys. For each of the sorting functions, the default sorting order is ascending.

    collSort(coll :: LIST OF ANY, config :: MAP?) :: (LIST? OF ANY?)

    You can use the collSort function to sort a list of values. The function returns a new, sorted list, containing the original list elements. By default, it sorts the values in ascending order, but you can modify this behavior by providing a map configuration, such as in the following example. This query sorts the names in descending alphabetical order of the first 10 airports located in the US:

    MATCH (a:airport {country: 'US'}) 
    RETURN collSort(a.desc, { order: 'asc' }) as result

    collSortMaps(coll :: LIST OF MAP, config :: MAP) :: (LIST? OF ANY?)

    If you have a list of map objects, as opposed to a list of single data type values, you can use collSortMaps to sort the list of maps based on a map property. To do this, you must provide a configuration map that specifies the property name to sort, along with the sort direction. For example, the following configuration specifies the desc map property as the sort key, and the order of the sorting to be in ascending order:

    { key: 'desc', order: 'asc' }

    The following query returns a collection of map objects based on the desc property and code property of all airports located in the US. It then sorts this collection by the code property in descending order, before outputting the top 10 results:

    MATCH (a:airport {country: 'US'}) 
    WITH collSortMaps(COLLECT({name: a.desc, code: a.code}), {key: 'code', order: 'desc'}) as Sorted_Airports
    UNWIND Sorted_Airports as Airports
    RETURN Airports.name, Airports.codeLIMIT 10

    collSortMulti(coll :: LIST OF MAP?, configs = [] :: LIST OF MAP, limit = -1 :: INTEGER?, skip = 0 :: INTEGER?) :: (LIST? OF ANY?)

    Extending the functionality of sorting lists of maps, collSortMulti enables you to sort on multiple map properties, as well as optionally providing limit and skip configurations. For example, the following configuration specifies that each map should be first sorted using the runways property in descending order, then by the desc property in ascending order (default), skipping the first 10 records, and limited to the next 20:

    [{ key: 'runways', order: 'desc' }, { key: 'desc' }], 20, 10

    The following query returns a collection of map objects using the preceding configuration:

    MATCH (a:airport {country: 'US'})
    WITH COLLECT({runways: a.runways, code: a.code, desc: a.desc}) as US_Airports
    WITH collSortMulti(US_Airports,[{ key: 'runways', order: 'desc' }, { key: 'desc' }], 20, 10) AS Sorted_Airports
    UNWIND Sorted_Airports AS Airports
    RETURN Airports.runways, Airports.desc

    collSortNodes(coll :: LIST OF NODE, config :: MAP) :: (LIST? OF NODE?)

    Some use cases require returning a sorted collection of nodes as opposed to maps of node values. For this, you can use collSortNodes, which sorts an input list of nodes based on the specified configuration, similar to collSortMaps. The following configuration defines the sort key as runways and the sort order as descending:

    { key: 'runways', order: 'desc' }

    This configuration is demonstrated in the following query, which returns the top 10 airports in the world ordered by the number of runways, with the airport with the largest number of runways first, and those with fewer airports last:

    MATCH (a:airport)
    WITH COLLECT(a) AS Airports
    WITH collSortNodes(Airports, {key: 'runways', order: 'desc'}) AS Sorted_Airports
    UNWIND Sorted_Airports as Airports
    RETURN Airports
    LIMIT 10

    Bulk load data using Neptune Database or Neptune Analytics

    The preceding queries use the publicly available air-routes dataset that can be ingested into your Neptune Database cluster or Neptune Analytics graph automatically using the %seed Workbench magic command. Alternatively, you can bulk load the data into either Neptune Database or Neptune Analytics from a Neptune notebook, using the following commands.

    For Neptune Database, you can use the bulk load API:

    %load --s s3://aws-neptune-customer-samples/airroutes/ --l <iam_role_arn> --f csv

    For more information about setting up IAM roles, and examples of initiating a Neptune Database bulk load using curl, see Example: Loading Data into a Neptune DB Instance.

    For Neptune Analytics, you can use the neptune.load command with CALL:

    CALL neptune.load({
    source: 's3://aws-neptune-customer-samples-us-east-1/airroutes/',
    region: 'us-east-1',
    format: 'CSV',
    failOnError: true,
    concurrency: 1
    })

    Note that you are responsible for any costs incurred while trying out these examples on your Neptune Database cluster or Neptune Analytics graph.

    Conclusion

    In this post, we described how Neptune has extended the openCypher graph query language to provide you with additional functionality that in some cases wasn’t previously available, meaning queries needed to be segregated between the graph and application code, creating a more complex, highly coupled solution architecture.

    You can find a complete list of improvements and fixes in the release notes. The following are a few ways to get started with this release:

    • Create your first Neptune cluster as part of the AWS Free Tier
    • Upgrade your existing Neptune cluster to 1.4.2.0 or later to take advantage of the latest features
    • Use the open source graph-explorer application to quickly visualize and explore graphs on Neptune
    • Run the open source graph-notebook library on Jupyter or JupyterLab notebooks to interactively query and build graph applications on Neptune

    Leave your questions in the comments section.


    About the authors

    Kevin Phillips is a Sr. Neptune Specialist Solutions Architect working in the UK at Amazon Web Services, having spent the last 4 years working with customers across EMEA to get started and accelerate with graphs. He has over 20 years of development and solutions architectural experience, which he uses to help support and guide customers.

    Source: Read More

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleImpactful tips to enhance your website’s accessibility
    Next Article Connect Amazon Bedrock Agents with Amazon Aurora PostgreSQL using Amazon RDS Data API

    Related Posts

    Development

    GPT-5 is Coming: Revolutionizing Software Testing

    July 22, 2025
    Development

    Win the Accessibility Game: Combining AI with Human Judgment

    July 22, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    CVE-2025-37984 – Linux Kernel ECDsa Integer Overflow Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    CVE-2025-46548 – Pekko Management Basic Authentication Misapplication

    Common Vulnerabilities and Exposures (CVEs)

    cgames – collection of three ncurses games

    Linux

    CVE-2025-40635 – Comerzzia Backoffice: Sales Orchestrator SQL Injection Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    Highlights

    CVE-2025-5644 – Radare2 Use After Free Vulnerability in r_cons_flush Function

    June 5, 2025

    CVE ID : CVE-2025-5644

    Published : June 5, 2025, 7:15 a.m. | 4 hours, 25 minutes ago

    Description : A vulnerability, which was classified as problematic, has been found in Radare2 5.9.9. Affected by this issue is the function r_cons_flush in the library /libr/cons/cons.c of the component radiff2. The manipulation of the argument -T leads to use after free. Local access is required to approach this attack. The complexity of an attack is rather high. The exploitation is known to be difficult. The exploit has been disclosed to the public and may be used. The real existence of this vulnerability is still doubted at the moment. The name of the patch is 5705d99cc1f23f36f9a84aab26d1724010b97798. It is recommended to apply a patch to fix this issue. The documentation explains that the parameter -T is experimental and “crashy”. Further analysis has shown “the race is not a real problem unless you use asan”. A new warning has been added.

    Severity: 2.5 | LOW

    Visit the link for more details, such as CVSS details, affected products, timeline, and more…

    Android Security Update – Patch for Vulnerabilities that Allows Privilege Escalation

    June 3, 2025

    The Game Pass hit STALKER 2 just got a huge Xbox award, and I can’t think of a game more deserving

    April 29, 2025

    AI-Powered Personalization: Redefining the Future of Customer Experience✨

    June 18, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.