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

      Sunshine And March Vibes (2025 Wallpapers Edition)

      May 22, 2025

      The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

      May 22, 2025

      How To Fix Largest Contentful Paint Issues With Subpart Analysis

      May 22, 2025

      How To Prevent WordPress SQL Injection Attacks

      May 22, 2025

      Sam Altman says ChatGPT’s viral Ghibli effect “forced OpenAI to do a lot of unnatural things”

      May 22, 2025

      How to get started with Microsoft Copilot on Windows 11

      May 22, 2025

      Microsoft blocks employees from sending emails that mention “Palestine” or “Gaza”

      May 22, 2025

      I missed out on the Clair Obscur: Expedition 33 Collector’s Edition but thankfully, the developers are launching something special

      May 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

      Perficient is Shaping the Future of Salesforce Innovation

      May 22, 2025
      Recent

      Perficient is Shaping the Future of Salesforce Innovation

      May 22, 2025

      Opal – Optimizely’s AI-Powered Marketing Assistant

      May 22, 2025

      Content Compliance Without the Chaos: How Optimizely CMP Empowers Financial Services Marketers

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

      Sam Altman says ChatGPT’s viral Ghibli effect “forced OpenAI to do a lot of unnatural things”

      May 22, 2025
      Recent

      Sam Altman says ChatGPT’s viral Ghibli effect “forced OpenAI to do a lot of unnatural things”

      May 22, 2025

      How to get started with Microsoft Copilot on Windows 11

      May 22, 2025

      Microsoft blocks employees from sending emails that mention “Palestine” or “Gaza”

      May 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 Article“Yes caviar is great, here’s a ham sandwich”
    Next Article Connect Amazon Bedrock Agents with Amazon Aurora PostgreSQL using Amazon RDS Data API

    Related Posts

    Development

    300 Servers and €3.5M Seized as Europol Strikes Ransomware Networks Worldwide

    May 23, 2025
    Development

    ViciousTrap Uses Cisco Flaw to Build Global Honeypot from 5,300 Compromised Devices

    May 23, 2025
    Leave A Reply Cancel Reply

    Continue Reading

    Camb AI Releases MARS5 TTS: A Novel Open Source Text to Speech Model for Insane Prosody

    Development

    CVE-2025-4906 – “PHPGurukul Notice Board System SQL Injection Vulnerability”

    Common Vulnerabilities and Exposures (CVEs)

    stagen – wlroots-based wayland compositor

    Development

    DLAP: A Deep Learning Augmented LLMs Prompting Framework for Software Vulnerability Detection

    Development

    Highlights

    Development

    How to Simplify AWS Multi-Account Management with Terraform and GitOps

    November 26, 2024

    In the past, in the world of cloud computing, a company’s journey often began with…

    The Importance of Content Moderation in Salesforce Communities

    February 12, 2025

    This AI Paper Presents SliCK: A Knowledge Categorization Framework for Mitigating Hallucinations in Language Models Through Structured Training

    May 14, 2024

    Xbox’s Age of Empires 2 and Age of Mythology: Retold are coming to PlayStation 5

    February 4, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

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