Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Golang Object Graph Mapper for Neo4j

License

NotificationsYou must be signed in to change notification settings

z5labs/gogm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Report CardActions StatusGoDoc

GoGM Golang Object Graph Mapper v2

Installation

go get github.com/mindstand/gogm/v2

Note: Do not use-u when installing. If you do, gogm will not compile.

This is caused by a dependency being updated to go1.18 making it incompatable with go1.17. In a future update, gogm will be updated to go1.18 eliminating this issue.

Features

  • Struct Mapping through thegogm struct decorator
  • Full support for ACID transactions
  • Underlying connection pooling
  • Support for HA Casual Clusters usingbolt+routing through theOfficial Neo4j Go Driver
  • Custom queries in addition to built in functionality
  • Builder pattern cypher queries usingMindStand's cypher dsl package
  • CLI to generate link and unlink functions for gogm structs.
  • Multi database support with Neo4j v4

What's new in V2

  • GoGM is an object now! This means you can have multiple instances of GoGM at a time
  • OpenTracing and Context Support
  • Driver has been updated from v1.6 to v4
  • Log interface, so anyone can use the logger of their choice instead of being forced to use logrus
  • Primary Key strategies to use any type of primary key. GoGM is no longer UUID only!
  • TLS now supported

| Note: GoGM v1 has been deprecated.

Usage

Primary Key Strategy

Primary key strategies allow more customization over primary keys. A strategy is provided to gogm on initialization.
Built in primary key strategies are:

  • gogm.DefaultPrimaryKeyStrategy -- just use the graph id from neo4j as the primary key
  • gogm.UUIDPrimaryKeyStrategy -- uuid's as primary keys
// Example of the internal UUID strategyPrimaryKeyStrategy{// StrategyName is the name to reference the strategyStrategyName:"UUID",// DBName is the name of the field in the databaseDBName:"uuid",// FieldName is the name of the field in go, this will validate to make sure all pk's use the same field nameFieldName:"UUID",// Type is the reflect type of the primary key, in this case it's a string but it can be any primitiveType:reflect.TypeOf(""),// GenIDFunc defines how new ids are generated, in this case we're using googles uuid libraryGenIDFunc:func() (idinterface{}) {returnuuid.New().String()    },}

Load Strategy

Load strategies allow control over the queries generated byLoad operations.Different strategies change the size of the queries sent to the database as well as the amount of work the database has to do.A load strategy is provided to gomg on initialization.

The defined load strategies are:

  • gogm.PATH_LOAD_STRATEGY -- Use cypher path queries to generate simple queries for load operations.
  • gogm.SCHEMA_LOAD_STRATEGY -- Leverage the GoGM schema to generate more complex queries for load operations which results in less work for the database.

Depending on your use case,PATH_LOAD_STRATEGY may result in higher latency.

Struct Configuration

text notates deprecation

Decorators that can be used

  • name=<name> -- used to set the field name that will show up in neo4j.
  • relationship=<edge_name> -- used to set the name of the edge on that field.
  • direction=<INCOMING|OUTGOING|BOTH|NONE> -- used to specify direction of that edge field.
  • index -- marks field to have an index applied to it.
  • unique -- marks field to have unique constraint.
  • pk=<strategy_name> -- marks field as a primary key and specifies which pk strategy to use. Can only have one pk, composite pk's are not supported.
  • properties -- marks that field is using a map. GoGM only supports properties fields ofmap[string]interface{},map[string]<primitive>,map[string][]<primitive> and[]<primitive>
  • - -- marks that field will be ignored by the ogm

Not on relationship member variables

All relationships must be defined as either a pointer to a struct or a slice of struct pointers*SomeStruct or[]*SomeStruct

Use; as delimiter between decorator tags.

Ex.

typeTdStringstringtypeMyNeo4jObjectstruct {// provides required node field// use gogm.BaseUUIDNode if you want to use UUIDs  gogm.BaseNodeFieldstring`gogm:"name=field"`Propsmap[string]interface{}`gogm:"properties;name=props"`//note that this would show up as `props.<key>` in neo4jIgnoreMebool`gogm="-"`UniqueTypeDefTdString`gogm:"name=unique_type_def"`Relation*SomeOtherStruct`gogm="relationship=SOME_STRUCT;direction=OUTGOING"`ManyRelation []*SomeStruct`gogm="relationship=MANY;direction=INCOMING"`}

GOGM Usage

package mainimport ("github.com/mindstand/gogm/v2""time")typetdStringstringtypetdIntint//structs for the example (can also be found in decoder_test.go)typeVertexAstruct {// provides required node fieldsgogm.BaseNodeTestFieldstring`gogm:"name=test_field"`TestTypeDefStringtdString`gogm:"name=test_type_def_string"`TestTypeDefInttdInt`gogm:"name=test_type_def_int"`MapPropertymap[string]string`gogm:"name=map_property;properties"`SliceProperty     []string`gogm:"name=slice_property;properties"`SingleA*VertexB`gogm:"direction=incoming;relationship=test_rel"`ManyA             []*VertexB`gogm:"direction=incoming;relationship=testm2o"`MultiA            []*VertexB`gogm:"direction=incoming;relationship=multib"`SingleSpecA*EdgeC`gogm:"direction=outgoing;relationship=special_single"`MultiSpecA        []*EdgeC`gogm:"direction=outgoing;relationship=special_multi"`}typeVertexBstruct {// provides required node fieldsgogm.BaseNodeTestFieldstring`gogm:"name=test_field"`TestTime   time.Time`gogm:"name=test_time"`Single*VertexA`gogm:"direction=outgoing;relationship=test_rel"`ManyB*VertexA`gogm:"direction=outgoing;relationship=testm2o"`Multi      []*VertexA`gogm:"direction=outgoing;relationship=multib"`SingleSpec*EdgeC`gogm:"direction=incoming;relationship=special_single"`MultiSpec  []*EdgeC`gogm:"direction=incoming;relationship=special_multi"`}typeEdgeCstruct {// provides required node fieldsgogm.BaseNodeStart*VertexAEnd*VertexBTeststring`gogm:"name=test"`}funcmain() {// define your configurationconfig:= gogm.Config{Host:"0.0.0.0",Port:7687,// deprecated in favor of protocol// IsCluster:                 false,Protocol:"neo4j",//also supports neo4j+s, neo4j+ssc, bolt, bolt+s and bolt+ssc// Specify CA Public Key when using +ssc or +sCAFileLocation:"my-ca-public.crt",Username:"neo4j",Password:"password",PoolSize:50,IndexStrategy:gogm.VALIDATE_INDEX,//other options are ASSERT_INDEX and IGNORE_INDEXTargetDbs:nil,// default logger wraps the go "log" package, implement the Logger interface from gogm to use your own loggerLogger:gogm.GetDefaultLogger(),// define the log levelLogLevel:"DEBUG",// enable neo4j go driver to logEnableDriverLogs:false,// enable gogm to log params in cypher queries. WARNING THIS IS A SECURITY RISK! Only use this when debuggingEnableLogParams:false,// enable open tracing. Ensure contexts have spans already. GoGM does not make root spans, only child spansOpentracingEnabled:false,// specify the method gogm will use to generate Load queriesLoadStrategy:gogm.PATH_LOAD_STRATEGY// set to SCHEMA_LOAD_STRATEGY for schema-aware queries which may reduce load on the database}// register all vertices and edges// this is so that GoGM doesn't have to do reflect processing of each edge in real time// use nil or gogm.DefaultPrimaryKeyStrategy if you only want graph ids// we are using the default key strategy since our vertices are using BaseNode_gogm,err:=gogm.New(&config,gogm.DefaultPrimaryKeyStrategy,&VertexA{},&VertexB{},&EdgeC{})iferr!=nil {panic(err)}//param is readonly, we're going to make stuff so we're going to do read writesess,err:=_gogm.NewSessionV2(gogm.SessionConfig{AccessMode:gogm.AccessModeWrite})iferr!=nil {panic(err)}//close the sessiondefersess.Close()aVal:=&VertexA{TestField:"woo neo4j",}bVal:=&VertexB{TestTime:time.Now().UTC(),}//set bi directional pointerbVal.Single=aValaVal.SingleA=bValerr=sess.SaveDepth(context.Background(),aVal,2)iferr!=nil {panic(err)}//load the object we just made (save will set the uuid)varreadinVertexAerr=sess.Load(context.Background(),&readin,aVal.UUID)iferr!=nil {panic(err)}fmt.Printf("%+v",readin)}

Migrating from V1 to V2

Initialization

Initialization in gogm v1

config:= gogm.Config{IndexStrategy:gogm.VALIDATE_INDEX,//other options are ASSERT_INDEX and IGNORE_INDEXPoolSize:50,Port:7687,IsCluster:false,//tells it whether or not to use `bolt+routing`Host:"0.0.0.0",Password:"password",Username:"neo4j",}err:=gogm.Init(&config,&VertexA{},&VertexB{},&EdgeC{})iferr!=nil {panic(err)}

Equivalent in GoGM v2

// define your configurationconfig:= gogm.Config{IndexStrategy:gogm.VALIDATE_INDEX,//other options are ASSERT_INDEX and IGNORE_INDEXPoolSize:50,Port:7687,IsCluster:false,//tells it whether or not to use `bolt+routing`Host:"0.0.0.0",Password:"password",Username:"neo4j",}// register all vertices and edges// this is so that GoGM doesn't have to do reflect processing of each edge in real time// use nil or gogm.DefaultPrimaryKeyStrategy if you only want graph ids_gogm,err:=gogm.New(&config,gogm.UUIDPrimaryKeyStrategy,&VertexA{},&VertexB{},&EdgeC{})iferr!=nil {panic(err)}gogm.SetGlobalGoGM(_gogm)
Note that we call gogm.SetGloablGogm so that we can still access it from a package level

Create a session

Creating a session in GoGM v1

sess,err:=gogm.NewSession(false)
Note this still works in v2, its using the global gogm to create the session. Also note this is making an instance of the deprecatedISession

Equivalent in GoGM v2

// this would also work with a local instance of gogm (localGogm.NewSessionV2)sess,err:=gogm.G().NewSessionV2(gogm.SessionConfig{AccessMode:gogm.AccessModeWrite})

Summary

  • Minimal change requires creating a global gogm, everything else should still work with ISession (gogm v1 session object)
  • ISession is now deprecated but still supported
  • SessionV2 is the new standard

GoGM CLI

CLI Installation

go get -u github.com/mindstand/gogm/v2/cmd/gogmcli

CLI Usage

NAME:   gogmcli - used for neo4j operations from gogm schemaUSAGE:   gogmcli [global options] command [command options] [arguments...]VERSION:   2.1.1COMMANDS:   generate, g, gen  to generate link and unlink functions for nodes   help, h           Shows a list of commands or help for one commandGLOBAL OPTIONS:   --debug, -d    execute in debug mode (default: false)   --help, -h     show help (default: false)   --version, -v  print the version (default: false)

Inspiration

Inspiration came from the Java OGM implementation by Neo4j.

Road Map

  • Schema Migration
  • Errors overhaul using go 1.13 error wrapping

How you can help

  • Report Bugs
  • Fix bugs
  • Contribute (refer to contribute.md)

[8]ページ先頭

©2009-2025 Movatter.jp