9 people like it.
Like the snippet!
Azure Cosmos DB - Graph get started
Translation of the Azure Cosmos DB Graph-get-started sample project (https://github.com/Azure-Samples/azure-cosmos-db-graph-dotnet-getting-started/tree/master/GraphGetStarted) A Cosmos DB account must first be created e.g. via the Azure Portal & from these the endpoint & authorization key are retrieved. Given these, the script creates: (i) Document Client (ii) Database (iii) Graph (aka Document Collection). From Gremlin expressions (strings) the command CreateGremlinQuery creates queries (IDocumentQueries) that can be executed to read from or modify the graph.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
|
// Azure Cosmos DB GraphGetStarted example
// https://github.com/Azure-Samples/azure-cosmos-db-graph-dotnet-getting-started/tree/master/GraphGetStarted
#r @"..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll"
#r @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Configuration.dll"
//#r @"..\packages\FSharp.Interop.Dynamic.3.0.0.0\lib\portable-net45+sl50+win\FSharp.Interop.Dynamic.dll"
//#r @"..\packages\FSharp.Data.2.4.2\lib\net45\FSharp.Data.dll"
// Microsoft.Azure
// ===============
#r @"..\packages\Microsoft.Azure.DocumentDB.1.17.0\lib\net45\Microsoft.Azure.Documents.Client.dll"
// #I @"..\packages\Microsoft.Azure.DocumentDB.1.17.0\runtimes\win7-x64\native"
// #r @"..\packages\Microsoft.Azure.Graphs.0.2.0-preview\lib\net451\Microsoft.Azure.Graphs.dll" // Superceded (but includes .net graph traversal)
#r @"..\packages\Microsoft.Azure.Graphs.0.2.4-preview\lib\net451\Microsoft.Azure.Graphs.dll" // Latest (only string Gremlin)
//#r @"..\packages\Microsoft.Azure.DocumentDB.1.17.0\runtimes\win7-x64\native\Microsoft.Azure.Documents.ServiceInterop.dll" // This one is native! Can't "#r" it.
open System
open Microsoft.Azure
open Microsoft.Azure.Documents
open Microsoft.Azure.Documents.Client
open Microsoft.Azure.Documents.Linq
open Microsoft.Azure.Graphs
open Microsoft.Azure.Graphs.Elements
open Newtonsoft.Json
// Add path to native DLL in F# interactive
let pathToAdd = @"C:\Users\UserName\Source\Repos\azure-cosmos-db-graph-dotnet-getting-started\packages\Microsoft.Azure.DocumentDB.1.17.0\runtimes\win7-x64\native"
Environment.SetEnvironmentVariable("Path",
Environment.GetEnvironmentVariable("Path") + ";" + pathToAdd)
let endpoint = "https://insert-endpoint-name-here.documents.azure.com:443/"
let authKey = "INSERT-AUTH-KEY-HERE=="
// Create Document Client
// "The DocumentClient class provides a client-side logical representation of the Azure DocumentDB service."
let client:DocumentClient =
new DocumentClient(
new Uri(endpoint),
authKey,
new ConnectionPolicy ( ConnectionMode = ConnectionMode.Direct, ConnectionProtocol = Protocol.Tcp ))
// Create database
let database:ResourceResponse<Database> =
client.CreateDatabaseIfNotExistsAsync( new Database ( Id = "graphdb" )).Result
// Create graph
let (graph:DocumentCollection) =
client.CreateDocumentCollectionIfNotExistsAsync( // Task<ResourceResponse<DocumentCollection>>
UriFactory.CreateDatabaseUri("graphdb"),
new DocumentCollection ( Id = "graphcollz" ),
new RequestOptions ( OfferThroughput = Nullable<int>(1000) ))
|> Async.AwaitTask // Task<T>->Async<T>, where T is ResourceResponse<DocumentCollection>
|> Async.RunSynchronously // Async<T> -> T (waits until the entire computation is completed)
|> (fun z->z.Resource) // ResourceResponse<DocumentCollection> -> DocumentCollection
let runGremlinQuery<'T> (dq:IDocumentQuery<'T>) : FeedResponse<'T> list =
[
while (dq.HasMoreResults)
do yield
dq.ExecuteNextAsync<'T>()
|> Async.AwaitTask // Task<T>->Async<T>, where T is ResourceResponse<DocumentCollection>
|> Async.RunSynchronously
]
// Try single queries
let queryAddVThomas = "g.addV('person').property('id', 'thomas').property('firstName', 'Thomas').property('age', 44)"
client.CreateGremlinQuery<Vertex>(graph, queryAddVThomas) |> runGremlinQuery<Vertex>
client.CreateGremlinQuery<Vertex>(graph, "g.V()") |> runGremlinQuery<Vertex>
let gremlinQueries =
dict [
"Cleanup", "g.V().drop()" ;
"AddVertex 1", "g.addV('person').property('id', 'thomas').property('firstName', 'Thomas').property('age', 44)" ;
"AddVertex 2", "g.addV('person').property('id', 'mary').property('firstName', 'Mary').property('lastName', 'Andersen').property('age', 39)" ;
"AddVertex 3", "g.addV('person').property('id', 'ben').property('firstName', 'Ben').property('lastName', 'Miller')" ;
"AddVertex 4", "g.addV('person').property('id', 'robin').property('firstName', 'Robin').property('lastName', 'Wakefield')" ;
"AddEdge 1", "g.V('thomas').addE('knows').to(g.V('mary'))" ;
"AddEdge 2", "g.V('thomas').addE('knows').to(g.V('ben'))" ;
"AddEdge 3", "g.V('ben').addE('knows').to(g.V('robin'))" ;
"UpdateVertex", "g.V('thomas').property('age', 44)" ;
"CountVertices", "g.V().count()" ;
"Filter Range", "g.V().hasLabel('person').has('age', gt(40))" ;
"Project", "g.V().hasLabel('person').values('firstName')" ;
"Sort", "g.V().hasLabel('person').order().by('firstName', decr)" ;
"Traverse", "g.V('thomas').outE('knows').inV().hasLabel('person')" ;
"Traverse 2x", "g.V('thomas').outE('knows').inV().hasLabel('person').outE('knows').inV().hasLabel('person')" ;
"Loop", "g.V('thomas').repeat(out()).until(has('id', 'robin')).path()" ;
"DropEdge", "g.V('thomas').outE('knows').where(inV().has('id', 'mary')).drop()" ;
"CountEdges", "g.E().count()" ;
//"DropVertex", "g.V('thomas').drop()";
]
// Run all of the queries
gremlinQueries
|> Seq.map (fun queryKVP ->
printf "%A" queryKVP.Key;
client.CreateGremlinQuery<obj>(graph, queryKVP.Value)
|> runGremlinQuery ) // Why does map stop after 4 iterations???
|> Seq.iter (fun z->printf "%A\r\n" z) // Whereas iter carries on until the end!??
|
namespace System
namespace Microsoft
namespace Microsoft.Azure
namespace Microsoft.Azure.Documents
namespace Microsoft.Azure.Documents.Client
namespace Microsoft.Azure.Documents.Linq
namespace Newtonsoft
namespace Newtonsoft.Json
val pathToAdd : string
Full name: Script.pathToAdd
type Environment =
static member CommandLine : string
static member CurrentDirectory : string with get, set
static member Exit : exitCode:int -> unit
static member ExitCode : int with get, set
static member ExpandEnvironmentVariables : name:string -> string
static member FailFast : message:string -> unit + 1 overload
static member GetCommandLineArgs : unit -> string[]
static member GetEnvironmentVariable : variable:string -> string + 1 overload
static member GetEnvironmentVariables : unit -> IDictionary + 1 overload
static member GetFolderPath : folder:SpecialFolder -> string + 1 overload
...
nested type SpecialFolder
nested type SpecialFolderOption
Full name: System.Environment
Environment.SetEnvironmentVariable(variable: string, value: string) : unit
Environment.SetEnvironmentVariable(variable: string, value: string, target: EnvironmentVariableTarget) : unit
Environment.GetEnvironmentVariable(variable: string) : string
Environment.GetEnvironmentVariable(variable: string, target: EnvironmentVariableTarget) : string
val endpoint : string
Full name: Script.endpoint
val authKey : string
Full name: Script.authKey
val client : DocumentClient
Full name: Script.client
Multiple items
type DocumentClient =
new : serviceEndpoint:Uri * authKey:SecureString * ?connectionPolicy:ConnectionPolicy * ?desiredConsistencyLevel:Nullable<ConsistencyLevel> -> DocumentClient + 7 overloads
member AuthKey : SecureString
member ConnectionPolicy : ConnectionPolicy
member ConsistencyLevel : ConsistencyLevel
member CreateAttachmentAsync : documentLink:string * attachment:obj * ?options:RequestOptions -> Task<ResourceResponse<Attachment>> + 3 overloads
member CreateAttachmentQuery<'T> : attachmentsUri:Uri * ?feedOptions:FeedOptions -> IOrderedQueryable<'T> + 11 overloads
member CreateConflictQuery : conflictsUri:Uri * ?feedOptions:FeedOptions -> IOrderedQueryable<Conflict> + 5 overloads
member CreateDatabaseAsync : database:Database * ?options:RequestOptions -> Task<ResourceResponse<Database>>
member CreateDatabaseIfNotExistsAsync : database:Database * ?options:RequestOptions -> Task<ResourceResponse<Database>>
member CreateDatabaseQuery : ?feedOptions:FeedOptions -> IOrderedQueryable<Database> + 2 overloads
...
Full name: Microsoft.Azure.Documents.Client.DocumentClient
--------------------
DocumentClient(serviceEndpoint: Uri, authKey: Security.SecureString, ?connectionPolicy: ConnectionPolicy, ?desiredConsistencyLevel: Nullable<ConsistencyLevel>) : unit
DocumentClient(serviceEndpoint: Uri, authKeyOrResourceToken: string, ?connectionPolicy: ConnectionPolicy, ?desiredConsistencyLevel: Nullable<ConsistencyLevel>) : unit
DocumentClient(serviceEndpoint: Uri, permissionFeed: Collections.Generic.IList<Permission>, ?connectionPolicy: ConnectionPolicy, ?desiredConsistencyLevel: Nullable<ConsistencyLevel>) : unit
DocumentClient(serviceEndpoint: Uri, authKey: Security.SecureString, serializerSettings: JsonSerializerSettings, ?connectionPolicy: ConnectionPolicy, ?desiredConsistencyLevel: Nullable<ConsistencyLevel>) : unit
DocumentClient(serviceEndpoint: Uri, authKeyOrResourceToken: string, serializerSettings: JsonSerializerSettings, ?connectionPolicy: ConnectionPolicy, ?desiredConsistencyLevel: Nullable<ConsistencyLevel>) : unit
Multiple items
type Uri =
new : uriString:string -> Uri + 5 overloads
member AbsolutePath : string
member AbsoluteUri : string
member Authority : string
member DnsSafeHost : string
member Equals : comparand:obj -> bool
member Fragment : string
member GetComponents : components:UriComponents * format:UriFormat -> string
member GetHashCode : unit -> int
member GetLeftPart : part:UriPartial -> string
...
Full name: System.Uri
--------------------
Uri(uriString: string) : unit
Uri(uriString: string, uriKind: UriKind) : unit
Uri(baseUri: Uri, relativeUri: string) : unit
Uri(baseUri: Uri, relativeUri: Uri) : unit
Multiple items
type ConnectionPolicy =
new : unit -> ConnectionPolicy
member ConnectionMode : ConnectionMode with get, set
member ConnectionProtocol : Protocol with get, set
member EnableEndpointDiscovery : bool with get, set
member MaxConnectionLimit : int with get, set
member MediaReadMode : MediaReadMode with get, set
member MediaRequestTimeout : TimeSpan with get, set
member PreferredLocations : Collection<string>
member RequestTimeout : TimeSpan with get, set
member RetryOptions : RetryOptions with get, set
...
Full name: Microsoft.Azure.Documents.Client.ConnectionPolicy
--------------------
ConnectionPolicy() : unit
type ConnectionMode =
| Gateway = 0
| Direct = 1
Full name: Microsoft.Azure.Documents.Client.ConnectionMode
field ConnectionMode.Direct = 1
type Protocol =
| Https = 0
| Tcp = 1
Full name: Microsoft.Azure.Documents.Client.Protocol
field Protocol.Tcp = 1
val database : ResourceResponse<Database>
Full name: Script.database
Multiple items
type ResourceResponse<'TResource (requires default constructor and 'TResource :> Resource)> =
inherit ResourceResponseBase
new : unit -> ResourceResponse<'TResource> + 1 overload
member Resource : 'TResource
Full name: Microsoft.Azure.Documents.Client.ResourceResponse<_>
--------------------
ResourceResponse() : unit
ResourceResponse(resource: 'TResource) : unit
Multiple items
type Database =
inherit Resource
new : unit -> Database
member CollectionsLink : string
member UsersLink : string
Full name: Microsoft.Azure.Documents.Database
--------------------
Database() : unit
DocumentClient.CreateDatabaseIfNotExistsAsync(database: Database, ?options: RequestOptions) : Threading.Tasks.Task<ResourceResponse<Database>>
val graph : DocumentCollection
Full name: Script.graph
Multiple items
type DocumentCollection =
inherit Resource
new : unit -> DocumentCollection
member ConflictsLink : string
member DefaultTimeToLive : Nullable<int> with get, set
member DocumentsLink : string
member IndexingPolicy : IndexingPolicy with get, set
member PartitionKey : PartitionKeyDefinition with get, set
member StoredProceduresLink : string
member TriggersLink : string
member UserDefinedFunctionsLink : string
Full name: Microsoft.Azure.Documents.DocumentCollection
--------------------
DocumentCollection() : unit
DocumentClient.CreateDocumentCollectionIfNotExistsAsync(databaseUri: Uri, documentCollection: DocumentCollection, ?options: RequestOptions) : Threading.Tasks.Task<ResourceResponse<DocumentCollection>>
DocumentClient.CreateDocumentCollectionIfNotExistsAsync(databaseLink: string, documentCollection: DocumentCollection, ?options: RequestOptions) : Threading.Tasks.Task<ResourceResponse<DocumentCollection>>
type UriFactory =
static member CreateAttachmentUri : databaseId:string * collectionId:string * documentId:string * attachmentId:string -> Uri
static member CreateCollectionUri : databaseId:string * collectionId:string -> Uri
static member CreateConflictUri : databaseId:string * collectionId:string * conflictId:string -> Uri
static member CreateDatabaseUri : databaseId:string -> Uri
static member CreateDocumentCollectionUri : databaseId:string * collectionId:string -> Uri
static member CreateDocumentUri : databaseId:string * collectionId:string * documentId:string -> Uri
static member CreatePartitionKeyRangesUri : databaseId:string * collectionId:string -> Uri
static member CreatePermissionUri : databaseId:string * userId:string * permissionId:string -> Uri
static member CreateStoredProcedureUri : databaseId:string * collectionId:string * storedProcedureId:string -> Uri
static member CreateTriggerUri : databaseId:string * collectionId:string * triggerId:string -> Uri
...
Full name: Microsoft.Azure.Documents.Client.UriFactory
UriFactory.CreateDatabaseUri(databaseId: string) : Uri
Multiple items
type RequestOptions =
new : unit -> RequestOptions
member AccessCondition : AccessCondition with get, set
member ConsistencyLevel : Nullable<ConsistencyLevel> with get, set
member DisableRUPerMinuteUsage : bool with get, set
member EnableScriptLogging : bool with get, set
member IndexingDirective : Nullable<IndexingDirective> with get, set
member OfferEnableRUPerMinuteThroughput : bool with get, set
member OfferThroughput : Nullable<int> with get, set
member OfferType : string with get, set
member PartitionKey : PartitionKey with get, set
...
Full name: Microsoft.Azure.Documents.Client.RequestOptions
--------------------
RequestOptions() : unit
Multiple items
type Nullable =
static member Compare<'T> : n1:Nullable<'T> * n2:Nullable<'T> -> int
static member Equals<'T> : n1:Nullable<'T> * n2:Nullable<'T> -> bool
static member GetUnderlyingType : nullableType:Type -> Type
Full name: System.Nullable
--------------------
type Nullable<'T (requires default constructor and value type and 'T :> ValueType)> =
struct
new : value:'T -> Nullable<'T>
member Equals : other:obj -> bool
member GetHashCode : unit -> int
member GetValueOrDefault : unit -> 'T + 1 overload
member HasValue : bool
member ToString : unit -> string
member Value : 'T
end
Full name: System.Nullable<_>
--------------------
Nullable()
Nullable(value: 'T) : unit
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken
Full name: Microsoft.FSharp.Control.Async
--------------------
type Async<'T>
Full name: Microsoft.FSharp.Control.Async<_>
static member Async.AwaitTask : task:Threading.Tasks.Task -> Async<unit>
static member Async.AwaitTask : task:Threading.Tasks.Task<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
val z : ResourceResponse<DocumentCollection>
property ResourceResponse.Resource: DocumentCollection
val runGremlinQuery : dq:IDocumentQuery<'T> -> FeedResponse<'T> list
Full name: Script.runGremlinQuery
val dq : IDocumentQuery<'T>
Multiple items
type IDocumentQuery =
Full name: Microsoft.Azure.Documents.Linq.IDocumentQuery
--------------------
type IDocumentQuery<'T> =
member ExecuteNextAsync<'TResult> : ?token:CancellationToken -> Task<FeedResponse<'TResult>> + 1 overload
member HasMoreResults : bool
Full name: Microsoft.Azure.Documents.Linq.IDocumentQuery<_>
Multiple items
type FeedResponse<'T> =
new : unit -> FeedResponse<'T> + 1 overload
member ActivityId : string
member CollectionQuota : int64
member CollectionSizeQuota : int64
member CollectionSizeUsage : int64
member CollectionUsage : int64
member ContentLocation : string
member Count : int with get, set
member CurrentResourceQuotaUsage : string
member DatabaseQuota : int64
...
Full name: Microsoft.Azure.Documents.Client.FeedResponse<_>
--------------------
FeedResponse() : unit
FeedResponse(result: Collections.Generic.IEnumerable<'T>) : unit
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
property IDocumentQuery.HasMoreResults: bool
IDocumentQuery.ExecuteNextAsync(?token: Threading.CancellationToken) : Threading.Tasks.Task<FeedResponse<obj>>
IDocumentQuery.ExecuteNextAsync<'TResult>(?token: Threading.CancellationToken) : Threading.Tasks.Task<FeedResponse<'TResult>>
val queryAddVThomas : string
Full name: Script.queryAddVThomas
val gremlinQueries : Collections.Generic.IDictionary<string,string>
Full name: Script.gremlinQueries
val dict : keyValuePairs:seq<'Key * 'Value> -> Collections.Generic.IDictionary<'Key,'Value> (requires equality)
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.dict
module Seq
from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val queryKVP : Collections.Generic.KeyValuePair<string,string>
val printf : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printf
property Collections.Generic.KeyValuePair.Key: string
type obj = Object
Full name: Microsoft.FSharp.Core.obj
property Collections.Generic.KeyValuePair.Value: string
val iter : action:('T -> unit) -> source:seq<'T> -> unit
Full name: Microsoft.FSharp.Collections.Seq.iter
val z : FeedResponse<obj> list
More information