NetworkX Query Tool
Project description
networkx-query
Versions following Semantic Versioning
Overview
NetworkX Query Tool
See documentation.
Installation
Install this library directly into an activated virtual environment:
$ pip install networkx-query
or add it to your Poetry project:
$ poetry add networkx-query
Usage
Searching nodes
import networkx as nx
from networkx_query import search_nodes, search_edges
g = nx.DiGraph()
g.add_node(1, product="chocolate")
g.add_node(2, product="milk")
g.add_node(3, product="coat")
g.add_edge(1, 2, action="shake")
g.add_edge(3, 2, action="produce")
for node_id in search_nodes(g, {"==": [("product",), "chocolate"]}):
print(node_id)
>> 1
Searching edges
for edge_id in search_edges(g, {"eq": [("action",), "produce"]}):
print(edge_id)
>> (3, 2)
Searching direct relation ship
With search_direct_relationships
you can made a query which filter edges on their :
- source node attributes
- edge attributes
- target node attributes
With this graph:
import networkx as nx
from networkx_query import search_direct_relationships
g = nx.DiGraph()
for i in range(30):
g.add_node(i, data=i)
for i in range(10, 30):
g.add_edge(i - 10, i, data=i)
We can filtering all edges with source node with data < 3:
list(search_direct_relationships(graph=g, source={"lt": ["data", 3]}))
[(0, 10), (1, 11), (2, 12)]
We can filtering all edges with:
- source node with data < 8
- edge with data > 15
list(search_direct_relationships(graph=g, source={"lt": ["data", 8]}, edge={"gt": ["data", 15]}))
>> [(6, 16), (7, 17)]
We can filtering all edges with:
- source node with data > 9
- edge with data > 15
- target node with data < 22
search_direct_relationships(
graph=g, source={"gt": ["data", 9]}, edge={"gt": ["data", 15]}, target={'lt': ["data", 22]}
)
)
>> [(10, 20), (11, 21)]
search_relationships
With :
g = nx.DiGraph()
g.add_node(1, product="a")
g.add_node(2, product="b")
g.add_node(3, product="c")
g.add_node(4, product="d")
g.add_edge(1, 2)
g.add_edge(1, 3, weight=2)
g.add_edge(1, 4)
g.add_edge(2, 4)
g.add_edge(3, 4)
You could find all path with multiple constraints:
list(search_relationships(
g,
{"eq": [("product",), "a"]},
PathCriteria(target={"eq": [("product",), "b"]}),
PathCriteria(target={"eq": [("product",), "d"]}),
))
# output: [[1, 2, 4]]
list(search_relationships(g, {"eq": [("product",), "a"]}, PathCriteria(target={"eq": [("product",), "c"]})))
# outptu: [[1, 3]]
or something more complex:
g.add_node(5, product="d")
g.add_node(6, product="d")
g.add_node(7, product="a")
g.add_node(8, product="a")
g.add_edge(7, 5, weight=2)
g.add_edge(7, 6, weight=2)
g.add_edge(8, 5, weight=2)
list(
search_relationships(
g,
{"eq": [("product",), "a"]}, # node 1, 7, 8
PathCriteria(
target={"eq": [("product",), "d"]}, edge={"eq": [("weight",), 2]}
), # edge 1-3, 7-5, 7-6, 8-5 node 4, 5, 6 -> no 1, 3, 4
)
)
# output: [[7, 5], [7, 6], [8, 5]]
list(
search_relationships(
g,
{"eq": [("product",), "a"]}, # node 1, 7, 8
PathCriteria(target={}, edge={"eq": [("weight",), 2]}), # edge 1-3, 7-5, 7-6, 8-5
PathCriteria(target={"eq": [("product",), "d"]}), # node 4, 5, 6 -> no 1, 3, 4
)
)
# output: [[1, 3, 4]]
Note the usage of PathCriteria(target={}, ..
to define a constraint based only on edge. {}
act as a wildcard.
API
Actually, we have:
All this function are based on prepare_query which return an Evaluator.
Quickly, Evaluator
are function with this signature: (context) -> bool, and Context
is a dictionary like structure (with in and [] methods, and support contains or (iter and getitem))
With networkX, node and edge attributes are dictionary like, so implementation of this three methods are very simple.
Query language
We define a little json query language like json-query-language against nodes or edges attributes.
Expressions
Main expression syntax turn around this:
{
operator_name : parameters
}
Basic matching expression
Test if a node/edge has an attribute named "my_property":
{
"has" : "my_property"
}
Test if a node/edge has an attribute product : { "definition": { "name": xxx }} with xxx equals to "chocolate".
{
"eq" : [ ("product", "definition", "name"), "chocolate"]
}
The tuple ("product", "definition", "name")
is a path in attribut dictionnary.
A Path is a single string or a tuple of string which represente a path in a tree (here a dictionary).
We support this operators:
Name | Alias | Parameters | Description |
---|---|---|---|
has | Path | Check if path exists in context. | |
contains | Path, str | Check if an attribut path exists and contains specified value. | |
eq | == |
Path, Any | Check if an attribut path exists and equals specified value. |
neq | != |
Path, Any | Check if an attribut path did not exists or not equals specified value. |
gt | > |
Path, Any | Check if an attribut path exists and greather that specified value. |
lt | < |
Path, Any | Check if an attribut path exists and lower that specified value. |
gte | >= |
Path, Any | Check if an attribut path exists and greather or equals that specified value. |
lte | <= |
Path, Any | Check if an attribut path exists and lower or equals that specified value. |
in | := |
Path, List[Any] | Check if an attribut path exists and attribut value in specified values. |
Boolean composition of matching expression
We support this operators:
Name | Alias | Parameters | Description |
---|---|---|---|
and | && |
list of query | And operator. |
or | || | list of query | Or operator. |
xor | list of query | xor operator. | |
nxor | list of query | nxor operator. | |
not | ! |
query | Not operator. |
By default, a list of expressions is equivalent of an "AND" of this expressions.
Example:
{
'not': {
'has': ['group']
},
'has': 'application',
'eq': [('_link', 'other', 'weight'), 2]
}
is equivalent to:
{
'and': [
{
'not': [
{
'has': ['group']
}
]
},
{
'has': ['application']
},
{
'eq': [('_link', 'other', 'weight'), 2]
}
]
}
Wished Features
- add projection expression (a return like statement)
- add join relation ship
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for networkx_query-2.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e3de81206ce88e4ac7662c3ee982522cf89f2dfb1d89dc3bfed4a146f82c1769 |
|
MD5 | 85bd8e19813a3c665d8daac07d5abd41 |
|
BLAKE2b-256 | b9c03f60be30ee037dd0f428240eddede524609e4ab5115f5b1802e23667ea9a |