# Custom query modules

Before considering developing your custom query module, numerous [graph algorithms and utility
procedures](https://memgraph.com/docs/advanced-algorithms/available-algorithms) have already been
developed and are available as part of the MAGE library you can add to your
Memgraph installation. The MAGE library is included if you use Memgraph
Platform or Memgraph MAGE Docker images to run Memgraph.

You can modify them or implement custom query modules if they do not suit your needs. Memgraph supports extending
the query language with user-written procedures in **C**, **C++**, **Python**,
and **Rust**. These procedures are grouped into modules - **query module** files
(either `*.so` or `*.py` files).

## Developing your custom query module

To develop your custom query module procedures you can follow the guides for each language:

- [Python](https://memgraph.com/docs/custom-query-modules/python)
- [C](https://memgraph.com/docs/custom-query-modules/c)
- [C++](https://memgraph.com/docs/custom-query-modules/cpp)
- [Rust](https://memgraph.com/docs/custom-query-modules/rust)

Each language has its own advantages and disadvantages. 
Python, being a dynamic language, has slower execution but offers easier writing and debugging. In contrast, modules written in C, C++, and Rust offer faster execution but are more challenging to write and debug.

Use each of the guides to ease your development process.

Every single Memgraph installation comes with the example files. For C and C++
query modules, the example files `example_c.c` and `example_cpp.cpp` are located
in `/usr/lib/memgraph/query_modules/src`. Corresponding shared library files,
`example_c.so` and `example_cpp.so`, based on these source files, are located in
`/usr/lib/memgraph/query_modules`.

For Python query modules, there is an `example.py` file located in the `/usr/lib/memgraph/query_modules/`; there are no shared library files for Python query modules since the source is interpreted at runtime.

They were provided as examples of query modules for you to examine and learn how to use them in addition to the linked guides above. 

Each query module file corresponds to one query module, and file names are
mapped as query module names. For example, `example.so` will be mapped as
`example` module, and `py_example.py` will be mapped as `py_example` module. If
each module file has a procedure called `procedure` defined, those procedures
would be mapped in the Cypher query language as `example.procedure()` and
`py_example.procedure()` respectively.

Each query module file can contain multiple read and write procedures and functions. 

## Modifying the existing query modules 

If existing MAGE library modules almost meet your needs, consider modifying them and make a contribution to the Memgraph Mage library.

- Install the MAGE development environment from Docker Hub
- Build MAGE using the `docker build` command
- Build MAGE from source

Then, select a language you want to develop in. 

### Install MAGE and import query modules

**Docker Hub**

The following steps will guide you through installing MAGE development
        environment from Docker Hub and importing developed query modules.
        
        

        
### Download the MAGE image
 
        
        Run the following commands to get the Memgraph and MAGE Docker image and download the toolchain used for building modules:

```shell
docker run -p 7687:7687 memgraph/memgraph-mage:<version>       
```

        
### Develop a query
 

        When developing with Mage, take a look at the basis of developed [algorithms and utility procedures](https://github.com/memgraph/memgraph/tree/master/src/mage) and extend based on that. 

        If you are not extending the existing query modules, you can start from scratch by following these guides or using the API docs and knowledge to develop your query modules. 

        - [Python](https://memgraph.com/docs/custom-query-modules/python),
        - [C](https://memgraph.com/docs/custom-query-modules/c), 
        - [C++](https://memgraph.com/docs/custom-query-modules/cpp),
        - [Rust](https://github.com/memgraph/memgraph/tree/master/src/mage/rust/rsmgp-example). 

        
### Start the MAGE container
 

        Use the following command to start the MAGE container:

```shell
docker run --rm -p 7687:7687 --name mage memgraph-mage:<version>
```

        Be sure to replace the `<version>` with the specific version, for example:

```shell
docker run --rm -p 7687:7687 --name mage memgraph-mage:3.1.1
```

        
### Download and install toolchain and development dependencies
 

        Run the `make-dev-container.sh` script as `root` within the container to download the current toolchain version and install required `apt` packages:

```shell
docker exec -i -u root mage bash -c "./make-dev-container.sh"
````

        By running this command, your your container will have the following tools
        installed: `Python3`, `Rust`, `Clang`, `Make`, and `CMake` alongside the toolchain used to build both Memgraph and MAGE.

        
### Copy the files to the container
 

        Copy the files to the container named `mage`:

```shell
docker cp . mage:/mage/
```

        
### Enter the container
 

        Position yourself inside the container as `memgraph`:

```shell
docker exec -u memgraph -it mage /bin/bash
```
        
> **Note**
>
> If you performed the build locally, make sure to delete the `cpp/build` directory because you might be dealing with different architectures or problems with `CMakeCache.txt`.
>
>         To delete it, run:
>
> ```shell
rm -rf cpp/build
```

        
### Build MAGE
 

        Activate the toolchain and build MAGE:

```shell
source /opt/toolchain-v8/activate
python3 setup build 
```

        Then copy executables from `/mage/dist` to `/usr/lib/memgraph/query_modules` as `root`:
```shell
docker exec -i -u root mage bash -c "cp -vr /mage/dist/* /usr/lib/memgraph/query_modules/"
```

        
### Exit the container
 

        Everything should be ready to exit the container and load the query modules:

```shell
exit
```

        

**Docker Build**

Install MAGE with Docker Build.

    Create a Docker image directly from the [Memgraph GitHub
    repository](https://github.com/memgraph/mage), instead of pulling it from the
    Docker Hub.

    

    
### Download image or clone the repo
 

    Download a [specific release](https://github.com/memgraph/memgraph/releases) from
    the MAGE repository or clone the [repository](https://github.com/memgraph/memgraph) for the latest
    version.

```shell
git clone https://github.com/memgraph/memgraph.git && cd memgraph
```
    
### Build the MAGE tagged Docker image
  

    Run the following commands:

```shell
./tools/ci/mage-build/build-docker-image.sh --image-tag custom
```

    Verify that the build is successful by starting the built image:

```shell
docker run --rm -p 7687:7687 --name mage memgraph-mage:custom
```

    
### Develop modules
 

    When developing with Mage, take a look at the basis of developed [algorithms and utility procedures](https://github.com/memgraph/memgraph/tree/master/src/mage) and extend based on that. 

    If you are not extending the existing query modules, you can start from scratch by following these guides or using the API docs and knowledge to develop your query modules. 

    - [Python](https://memgraph.com/docs/custom-query-modules/python),
    - [C](https://memgraph.com/docs/custom-query-modules/c), 
    - [C++](https://memgraph.com/docs/custom-query-modules/cpp),
    - [Rust](https://github.com/memgraph/memgraph/tree/master/src/mage/rust/rsmgp-example). 

    
### Create the `dev` image
 
    
    To create the `dev` MAGE image, run the following command:

```shell
./tools/ci/mage-build/build-docker-image.sh --image-tag dev --build-type RelWithDebInfo
```

    
### Start the container
  
    
    Start the container with the following command:

```shell
docker run --rm -p 7687:7687 --name mage memgraph-mage:dev
```

    
### Enter the container
 

    Position yourself inside the container as `root`:

```shell
docker exec -u root -it mage /bin/bash
```
    
> **Note**
>
> If you performed the build locally, make sure to delete the `cpp/build` directory because you might be dealing with different architectures or problems with `CMakeCache.txt`.
>
>     To delete it, run:
>
> ```shell
rm -rf cpp/build
```

    
### Build MAGE
 

    Build MAGE with the option to copy executables from `mage/dist` to `/usr/lib/memgraph/query_modules`:

```shell
python3 setup build -p /usr/lib/memgraph/query_modules/
```

    
### Exit the container
 

    Everything should be ready to exit the container and load the query modules:

```shell
exit
```

    

**From source**

Follow the steps if you want to use the MAGE library with [installed Linux based
    Memgraph package](https://memgraph.com/docs/getting-started/install-memgraph) and create custom query modules. 

    

    
### Set up the build environment
 

    Follow the [Build from source
    guide](https://memgraph.com/docs/advanced-algorithms/install-mage#build-from-source-linux) to clone
    the Memgraph repository, install the build dependencies, set up the
    toolchain and install the Rust and Python dependencies.

    
### Build MAGE
 

    Run the following commands from the root of the repository:

```shell
source /opt/toolchain-v8/activate
./build.sh --mage only
```

    The built query modules land in `build/mage/dist`.

    
### Install the query modules
 

    Install the modules to `/usr/lib/memgraph/query_modules`, the directory
    Memgraph loads query modules from:

```shell
sudo cmake --install build --component mage --prefix /usr
```

    
> **Info**
>
> While developing, you can skip the install step on every rebuild by
>     pointing Memgraph directly at the build output instead: set
>     `--query-modules-directory=<repo>/build/mage/dist` in
>     `/etc/memgraph/memgraph.conf` (or on the command line).

    
### Develop modules
 

    When developing with Mage, take a look at the basis of developed [algorithms and utility procedures](https://github.com/memgraph/memgraph/tree/master/src/mage) and extend based on that. 

    If you are not extending the existing query modules, you can start from scratch by following these guides or using the API docs and knowledge to develop your query modules. 

    - [Python](https://memgraph.com/docs/custom-query-modules/python),
    - [C](https://memgraph.com/docs/custom-query-modules/c), 
    - [C++](https://memgraph.com/docs/custom-query-modules/cpp),
    - [Rust](https://github.com/memgraph/memgraph/tree/master/src/mage/rust/rsmgp-example). 

    
### Rebuild and load your changes
 
    
    Make sure your Memgraph instance is running:

```
sudo systemctl status memgraph.service
```

    After changing a module, rebuild and reinstall (the install step isn't
    needed if you pointed `--query-modules-directory` at `build/mage/dist`):

```shell
./build.sh --mage only --dev
sudo cmake --install build --component mage --prefix /usr
```

    Then reload the query modules in a running instance:

```cypher
CALL mg.load_all();
```

    

**MAGE x NVIDIA cuGraph**

    
### Download Memgraph source code
 
    Download the Memgraph source code from GitHub:

```shell
git clone https://github.com/memgraph/memgraph.git && cd memgraph
```

    
### Build the image
 
    
    Build the *MAGE × cuGraph*-tagged Docker image:
    
```shell
./tools/ci/mage-build/build-docker-image.sh --cugraph --image-tag "cugraph"
```

    
### Run the image
 

    Start Memgraph-MAGE with the following command:

```shell
docker run --rm --gpus all -p 7687:7687 -p 7444:7444 --name mage memgraph/memgraph-mage:cugraph
```
    

    If you made any changes while the Docker container was running, you need to stop
    the container and rebuild the image. 

    

## Querying

Query modules are loaded into Memgraph on startup, so if your instance was
already running, you need to execute the following query inside one of the
querying platforms ([mgonsole](https://memgraph.com/docs/getting-started/cli), [Memgraph
Lab](https://memgraph.com/docs/data-visualization) or a [client library](https://memgraph.com/docs/client-libraries)) to load
them:

```cypher
CALL mg.load_all();
```

Run a query and test your module. All procedures are called using the `CALL`
clause:

```cypher
MERGE (start:Node {id: 0})-[:RELATION]->(:Node {id: 1})-[:RELATION]->(:Node {id: 2})
CALL random_walk.get(start, 2) YIELD path
RETURN path
```
