diff --git a/pages/advanced-algorithms/available-algorithms.mdx b/pages/advanced-algorithms/available-algorithms.mdx index 749aa1ea2..f78ac53fa 100644 --- a/pages/advanced-algorithms/available-algorithms.mdx +++ b/pages/advanced-algorithms/available-algorithms.mdx @@ -112,6 +112,7 @@ If you want to know more and learn how this affects you, read our [announcement] | [periodic](/advanced-algorithms/available-algorithms/periodic) | C++ | A module containing procedures for periodically running difficult and/or memory/time consuming queries. | | [refactor](/advanced-algorithms/available-algorithms/refactor) | C++ | The refactor module provides utilities for changing nodes and relationships. | | [rust_example](https://github.com/memgraph/memgraph/tree/master/mage/rust/rsmgp-example) | Rust | Example of a basic module with input parameters forwarding, made in Rust. | +| [search](/advanced-algorithms/available-algorithms/search) | C++ | A module for finding nodes by comparing one or more of their properties against a value with a comparison operator, without writing the equivalent `MATCH` and `WHERE` clauses. | | [set_property](/advanced-algorithms/available-algorithms/set_property) | C++ | A module for dynamical access and editing of node and relationship properties. | | [temporal](/advanced-algorithms/available-algorithms/temporal) | Python | A module that provides functions to handle temporal (time-related) operations and offers extended capabilities compared to the date module. | | [text](/advanced-algorithms/available-algorithms/text) | C++ | The `text` module offers a toolkit for manipulating strings. | @@ -202,6 +203,8 @@ Running `SHOW QUERY CALLABLE MAPPINGS` requires the `CONFIG` privilege. | apoc.refactor.renameType | Changes the relationship type | [refactor.rename_type()](/advanced-algorithms/available-algorithms/refactor#rename_type) | | apoc.refactor.rename.typeProperty | Renames the property of a relationship | [refactor.rename_type_property()](/advanced-algorithms/available-algorithms/refactor#rename_type_property) | | apoc.refactor.mergeNodes | Merges properties, labels and relationships for source nodes to target node | [refactor.mergeNodes()](/advanced-algorithms/available-algorithms/refactor#mergenodes) | +| apoc.search.node | Finds nodes by a label-property map and comparison operator, returning each matching node once | [search.node()](/advanced-algorithms/available-algorithms/search#node) | +| apoc.search.nodeAll | Finds nodes by a label-property map and comparison operator, returning one row per matching property | [search.node_all()](/advanced-algorithms/available-algorithms/search#node_all) | | apoc.text.join | Joins all strings into a single one with given delimiter | [text.join()](/advanced-algorithms/available-algorithms/text#join) | | apoc.text.indexOf | Finds the index of first occurrence of a substring within a string | [text.indexOf()](/advanced-algorithms/available-algorithms/text#indexof) | | apoc.text.regexGroups | Returns all matched subexpressions of regex on provided text | [text.regexGroups()](/advanced-algorithms/available-algorithms/text#regexgroups) | diff --git a/pages/advanced-algorithms/available-algorithms/_meta.ts b/pages/advanced-algorithms/available-algorithms/_meta.ts index 885416252..d81ceb7e4 100644 --- a/pages/advanced-algorithms/available-algorithms/_meta.ts +++ b/pages/advanced-algorithms/available-algorithms/_meta.ts @@ -59,6 +59,7 @@ export default { "path": "path", "periodic": "periodic", "refactor": "refactor", + "search": "search", "set_cover": "set_cover", "set_property": "set_property", "temporal": "temporal", diff --git a/pages/advanced-algorithms/available-algorithms/search.mdx b/pages/advanced-algorithms/available-algorithms/search.mdx new file mode 100644 index 000000000..c2c304b7a --- /dev/null +++ b/pages/advanced-algorithms/available-algorithms/search.mdx @@ -0,0 +1,194 @@ +--- +title: search +description: Look up nodes by a label and property value in Memgraph using a comparison operator, without writing the equivalent MATCH and WHERE clauses. +--- + +import { Callout } from 'nextra/components' +import { Cards } from 'nextra/components' +import GitHub from '/components/icons/GitHub' + +# search + +The `search` module finds nodes by comparing one or more of their properties +against a value. You describe which properties to search with a `{label: +property}` map, pick a comparison operator, and provide the value to compare +against, instead of writing the equivalent `MATCH` and `WHERE` clauses yourself. +When a matching label-property index exists, it is used automatically. + + + } + title="Source code" + href="https://github.com/memgraph/memgraph/blob/master/mage/cpp/search_module/search_module.cpp" + /> + + +| Trait | Value | +| ------------------ | ---------- | +| **Module type** | module | +| **Implementation** | C++ | +| **Parallelism** | sequential | + +## Procedures + +Both procedures take the same arguments and differ only in how they handle a +node that matches more than once: `search.node` returns each matching node once, +while `search.node_all` returns one row per property that matches. + +### Arguments + +The `label_property_map` argument names the labels and properties to search. It +is a map from a label to a single property or to a list of properties, for +example `{Person: "name"}` or `{Person: ["name", "email"]}`. When a label maps +to a list of properties, a node matches if **any** of those properties matches +the value. The map may also be given as a JSON string, for example +`'{"Person": "name"}'` or `'{"Person": ["name", "email"]}'`. + +The `operator` argument selects the comparison to apply and is case-insensitive: + +| Operator | Meaning | +| ------------- | ---------------------------------------------------- | +| `=` / `exact` | Equal to the value. | +| `<>` | Not equal to the value. | +| `<` | Less than the value. | +| `<=` | Less than or equal to the value. | +| `>` | Greater than the value. | +| `>=` | Greater than or equal to the value. | +| `starts with` | String starts with the value. | +| `ends with` | String ends with the value. | +| `contains` | String contains the value. | +| `=~` | String matches the value as a regular expression. | + +The `starts with`, `ends with`, `contains` and `=~` operators only match string +properties. String comparisons are performed by codepoint, so uppercase letters +sort before lowercase ones. + +### `node()` + +Returns each node that matches the search criteria once, even if it matches on +more than one label or property. + + +This procedure is equivalent to **apoc.search.node**. + + +{

Input:

} + +- `label_property_map: Any` ➡ A map (or JSON string) from a label to the property or list of properties to search. +- `operator: string` ➡ The comparison operator to apply. Case-insensitive. +- `value: string` ➡ The value to compare each property against. If `null`, no nodes are returned. + +{

Output:

} + +- `node: Node` ➡ A node matching the search criteria. Each matching node is returned once. + +{

Usage:

} + +Given the following graph: + +```cypher +CREATE (:Person {name: 'Alice'}); +CREATE (:Person {name: 'Bob'}); +CREATE (:Person {name: 'Bobby'}); +CREATE (:Person {name: 'Carol'}); +``` + +The following query returns every `Person` whose `name` is greater than or equal +to `'Bob'`: + +```cypher +CALL search.node({Person: 'name'}, '>=', 'Bob') YIELD node +RETURN node.name AS name ORDER BY name; +``` + +```plaintext ++----------------------------+ +| name | ++----------------------------+ +| "Bob" | +| "Bobby" | +| "Carol" | ++----------------------------+ +``` + +The `label_property_map` can also be given as a JSON string: + +```cypher +CALL search.node('{"Person": "name"}', 'exact', 'Bob') YIELD node +RETURN node.name AS name; +``` + +```plaintext ++----------------------------+ +| name | ++----------------------------+ +| "Bob" | ++----------------------------+ +``` + +When a node carries several of the searched labels, `search.node` still returns +it only once: + +```cypher +CREATE (:P {name: 'x'}); +CREATE (:M {title: 'x'}); +CREATE (:P:M {name: 'x', title: 'x'}); +``` + +```cypher +CALL search.node({P: 'name', M: 'title'}, 'exact', 'x') YIELD node +RETURN count(node) AS c; +``` + +```plaintext ++----------------------------+ +| c | ++----------------------------+ +| 3 | ++----------------------------+ +``` + +### `node_all()` + +Returns a node once for every property that matches the search criteria, so a +node that matches on several properties or labels appears in more than one row. + + +This procedure is equivalent to **apoc.search.nodeAll**. + + +{

Input:

} + +- `label_property_map: Any` ➡ A map (or JSON string) from a label to the property or list of properties to search. +- `operator: string` ➡ The comparison operator to apply. Case-insensitive. +- `value: string` ➡ The value to compare each property against. If `null`, no nodes are returned. + +{

Output:

} + +- `node: Node` ➡ A node matching the search criteria, returned once per matching property. + +{

Usage:

} + +Given the following graph, where one movie matches on `title` and the other on +`tagline`: + +```cypher +CREATE (:Movie {title: 'Matrix', tagline: 'Neo'}); +CREATE (:Movie {title: 'Heat', tagline: 'Matrix'}); +``` + +Searching both properties returns both movies: + +```cypher +CALL search.node_all('{"Movie": ["title", "tagline"]}', 'exact', 'Matrix') YIELD node +RETURN node.title AS title ORDER BY title; +``` + +```plaintext ++----------------------------+ +| title | ++----------------------------+ +| "Heat" | +| "Matrix" | ++----------------------------+ +```