-
Notifications
You must be signed in to change notification settings - Fork 35
Rest Configuration
In order to map a rest data store you will need to get familiar with both Mustache and JMustache.
After you are familiar with Mustache you can start writing your templates.
The search template will generate a query for your rest data store.
Your template will generate with a json that will look like:
{
"limit": 100000,
"predicates": {
"and": {
"predicates": [
{"op": "op", "value": "value", "key": "key"}
],
"complex": ["complex_operation"],
"children":[
{
"predicates": {
"and": {},
"or": {}
}
}
]
},
"or": {
"predicates": [
{"op": "op", "value": "value", "key": "key"}
],
"complex": ["complex_operation"],
"children":[
{
"predicates": {
"and": {},
"or": {}
}
}
]
}
}
}
The search template can be used as a sub template to generate the child constraints.
You don't have to support every operation, what you'r not supporting will just be done in memory sometimes in the expense of performance.
For example you can refer to the elastic search template which supports all the operations.
The add template will generate an add query for your rest data store.
Your template will generate with a json that will look like:
{
"prop":[
{
"key": "key",
"value": "value"
}
]
}
The bulk template can generate a bulk insertion if you support it and uses the add template as a sub template.
Your template will generate with a json that will look like:
{
"bulk": [
{
"url": {"resource": "resource", "type": "type", "id": "id"},
"object": {
"prop": [
{
"key": "key",
"value": "value"
}
]
}
}
]
}
You don't have to implement anything you don't intend to use.
To map data from a rest data store your mapping file will look like:
{
"class": "org.unipop.rest.RestSourceProvider",
"baseUrl": "http://your.url",
"add":{
"url": "/{{resource}}/{{type}}/{{id}}",
"template": "{ {{#prop}}\"{{key}}\":\"{{value}}\"{{^-last}}, {{/-last}}{{/prop}} }",
"commit": {
"url":"/{{resource}}/_refresh"
},
"bulk":{
"url": "/_bulk",
"template": "resources/bulk.mustache"
}
},
"search":{
"url": "{{resource}}/_search",
"template": "resources/search.mustache"
},
"delete":{
"url" : "{{resource}}/{{type}}/{{id}}"
},
"resultPath": "hits.hits",
"opTranslator": {
"eq": "term",
"within": "terms"
},
"complexTranslator":[
{"op": "gt", "template": "{ \"range\": { {{key}}: { \"gt\": {{value}} } } }"}
],
"vertices": [],
"edges": []
}
This example is specifically for elasticsearch.
- baseUrl - The base url for all of your queries.
- add - Optional, the add query template contains a url template which will be concatenated to the base url
at query time, the template itself, commit url if necessary and bulk template also optional. - search - Your search template contains a url template and the template itself.
- delete - Optional, delete url template.
- resultPath - The path to the result in the returned JSON.
- opTranslator - Translate gremlin operations to keywords for your query, basic queries that are built the same.
- complexTranslator - Translate complex operations where each operation, complex queries that built differently.
Every template can be written inline or as a file path.
Each complex operator is chosen by a matcher.
We currently have three matchers available.
- Op Matcher - Chosen by the operation of the predicate.
{"op": "some_operation", "template": "some_template"}
- Multi Op Matcher - Like op matcher but for multiple operations.
{"ops": ["some_operation1", "some_operation2"], "template": "some_template"}
- Key Matcher - Chosen by the key of the predicate.
{"key": "some_key", "template": "some_template"}
Each element we map requires some more information from us about it's whereabouts, we'll need to provide a resource.
{
"resource": "a_resource"
}
So a vertex will look like:
{
"resource": "a_resource",
"id": "an_id",
"label": "a_label",
"properties": {}
}
If we require each field can be represented as a path.
ie. in elasticsearch it will look something like '@_source.someField'.
An edge will look like:
{
"resource": "a_resource",
"id": "an_id",
"label": "a_label",
"properties": {},
"outVertex": {
"ref": true,
"id": "out_vertex_id",
"label": "out_vertex_label"
},
"inVertex": {
"ref": true,
"id": "in_vertex_id",
"label": "in_vertex_label"
}
}
Currently only one way to represent an edge from a rest data source is available.