Using Azure CosmosDB DocumentDB API with Graph API - node.js

What I would like to be able to do:
Save schemaless JSON to documents
Connect those documents arbitrarily
Get recursive tree of documents based on aforementioned connections, like for example:
{
"name": "Document 1",
"includes": [
{
"name": "Document 2.1"
"includes": [
{
"name": "Document 3",
"includes": []
}
]
},
{
"name": "Document 2.2",
"includes": []
}
]
}
Current status of my setup:
CosmosDB instance configured with Graph (Gremlin) API
Possible to create (JSON) documents through DocumentDB API
Possible to created edges to documents through Graph API
Using Node.js SDKs
Questions:
Is it possible to save JSON objects as vertices through Graph API? It allows creating vertices with g.addV('person').property('id', 'thomas').property('firstName', 'Thomas').property('age', 44).property('userid', 1) but something like g.addV({ firstName: 'Thomas' }) does not seem to work.
If I add documents through DocumentDB API and edges between them through Graph API and traverse through the graph, results only include IDs of the documents, not other properties. Is it possible to populate the documents somehow?
Example traversal query:
g.V('03e0576f-2ff7-6109-5ed5-237b43191354').repeat(out('includes')).until(not(out('includes'))).simplePath().dedup().tree().by('id')
Result from this query:
[{
"03e0576f-2ff7-6109-5ed5-237b43191354": {
"key": "03e0576f-2ff7-6109-5ed5-237b43191354",
"value": {
"7fab4007-c80c-ba21-f5d3-8eb353ea3279": {
"key": "7fab4007-c80c-ba21-f5d3-8eb353ea3279",
"value": {
"eec55fbd-6900-130d-247f-fb437b093711": {
"key": "eec55fbd-6900-130d-247f-fb437b093711",
"value": {}
},
"cfd14a8c-1ac3-6cc3-e2a4-ac3f250478e1": {
"key": "cfd14a8c-1ac3-6cc3-e2a4-ac3f250478e1",
"value": {
"acac136a-3bd4-831c-df6e-e5b95e593b9a": {
"key": "acac136a-3bd4-831c-df6e-e5b95e593b9a",
"value": {}
}
}
}
}
}
}
}
}]

Yes, it is possible to insert documents both through the Graph API and through the Document API. However, Cosmos expects a specific GraphSON format for the documents in order for all of their properties to be picked up during graph traversal.
I'd recommend taking a look at both Vertex Properties and GraphSON from the Tinkerpop documentation to start to get a better idea about these topics.
When adding a document through Gremlin the syntax is a name value comma separated for all properties you want to add. Try this:
g.addV('label', 'human', 'name', 'jesse', 'age', 27)
Now if you go to the Azure portal and execute a SQL query SELECT * FROM c you'll be able to see the format that Cosmos has translated your document into.

Related

How to create a nested collection in Azure purview through api using postman?

I am trying to create a nested collection in a purview through api using postman.
I was able to create a one subcollection under my existing collection in a purview.
Is there a way to create a bunch of subcollections under the existing collection at once?
Data Hierarchy existingCollection > hello > hello-sub
I've tried this as below.
`
{
"value": [
{
"name": "hello",
"description": "hello description",
"friendlyName": "hello",
"parentCollection": {
"referenceName": "existingCollection"
}
},
{
"name": "hello-sub",
"friendlyName": "hello-sub",
"parentCollection": {
"referenceName": "hello"
}
}
]
}
`
When I checked the purview, there is one hello collection created outside of exsitingCollection. I don't see hello-sub collection at all.
Can anyone help me create a nested collection under my existing collection in a purview please?
Thank you in advance!!!

Graph DB Gremlin query for nested properties

I am storing the below data in azure cosmos graph db.
"properties": {
"A": {
"value": "prop1 new value"
},
"settings": {
"DigitalInput": {
"Input1": {
"nTransIn1": {
"tagName": {
"value": ""
}
}
},
"Input2": {
"nTransIn2": {
"tagName": {
"value": ""
}
}
}
When I am trying to query by single property
g.V().has('s_objectId',within('9d8cf5c6-7b5f-4d0b-af70-bf516f219d73')).
valueMap("p_A")
is giving expected output but how to retrieve with property 'settings' which has nested properties. When I try
g.V().has('s_objectId',within('9d8cf5c6-7b5f-4d0b-af70-bf516f219d73')).
valueMap("p_settings")
it is not giving the correct output as the setting property is stored like below in graph database
"p_settings.DigitalInput.Input1.nTransIn1.tagName": [
{
"id": "6057e448-a2e8-48e4-820f-5396003bdcae",
"value": ""
}
],
Your queries and sample data seem to use different field names. It would be helpful if you could add to the question an addV step that creates the structure you are using in a way that can be tested with TinkerGraph.
In general with Gremlin, the way to access map structures is to select your way into it. Something like
valueMap("p_A").select("p_settings")

Azure Search service gives error "Expected a JSON object, array or literal" on spatial query

I am trying to use Azure Search Service for querying data based on spatial data.
I want to filter data based on geography. The query tried out in search explorer is search=*&$filter=geo.distance(geolocation, geography'POINT(9.2869001 47.3532887)') le 50
Type defined for geolocation field is Ed.GeographyPoint and attributes set are filterable and retrievable
But i am not getting results, instead getting message "Expected a JSON object, array or literal" in the result window.
What is wrong with the query is here.
I am using Standard plan for Azure and API version used is API version: 2016-09-01
Does your geolocation field has format similar to below?
"location": { "type": "Point", "coordinates": [ -121.355, 47.71 ], "crs": { "type": "name", "properties": { "name": "EPSG:4326" } } }

Can I get CosmosDB graph to return edge details for vertex objects in query results?

Consider the following simple gremlin query: g.V("some_id")
When executed against my CosmosDB graph database from the "Data Explorer" tab of the Azure web UI, I get the following results:
[{
"id": "some_id",
"label": "some_type
"type": "vertex",
"outE": {
"some_edge": [{
"id": "75b3c6ff-efdf-4a88-8cf6-aa395ef28bf7",
"inV": "another_id"
},
{
"id": "f3703292-12b9-44bc-a16f-26bac75f3420",
"inV": "yet_another_id"
}
]
},
"properties": {
"some_property": [{
"id": "50bda5cb-08ab-4727-b212-5ba4e829db3e|organizationId",
"value": "hi there"
}]
}
}]
When I execute the same exact query against the same exact database using the gremlin websocket endpoint, I get the following results:
[{
"id": "some_id",
"label": "some_type
"type": "vertex",
"properties": {
"some_property": [{
"id": "50bda5cb-08ab-4727-b212-5ba4e829db3e|organizationId",
"value": "hi there"
}]
}
}]
What happened to the edges (the "outE" JSON key)? Only the "properties" key is included, but man, I need those edges! How do I adjust the output format to include them?
This looks like it is an artifact of the way that the data explorer shows and parses the data returned by the underlying engine. Since the edges are not properties of the Vertexes I don't think that these should be included as part of the Vertex returned by the query. If you want to return the vertex and the associated edges you can do that using a query like this which works in the gremlin console and via the driver:
g.V('some-id').as('b').bothE().as('e').select ('b', 'e')

Pagination with per-row access rights

Hi I am using CouchDB and assuming I have an articles document with the field users, containing an array of user IDs that are allowed to view this article.
Example scenario, there will be a paginated table view showing 10 articles per page, my controller will retrieve the first 10 articles from CouchDB then perform the access rights check one by one on the returned articles. But the current user may only have view access rights on say, 8 of them, therefore the table will only show 8 articles instead of 10.
What are the best practice of handling such situation besides implementing the access rights logic on the CouchDB layer?
To accomplish this, I would simply use a view keyed on the users field:
function (doc) {
doc.users.forEach(function (user) {
emit([ user ]);
});
}
I emitted an array with just 1 item in this case. I presume you'd also emit something like doc.created in order to have your articles sorted, you would simply add them after user in that array.
The view results would look something like:
{
"rows": [
{ "id": "<article-1>", "key": [ "<user-1>", "<created>" ] },
{ "id": "<article-2>", "key": [ "<user-1>", "<created>" ] },
{ "id": "<article-3>", "key": [ "<user-1>", "<created>" ] },
{ "id": "<article-1>", "key": [ "<user-2>", "<created>" ] },
{ "id": "<article-1>", "key": [ "<user-3>", "<created>" ] }
]
}
You can simply paginate like you normally would with CouchDB. You simply use start_key=["<user-1>"]&end_key=["<user-1>","\ufff0"] in addition to the usual paging limit=10&skip=0 for page 1, limit=10&skip=10 for page 2, etc.

Resources