z5labs/gogm

Match multiple patterns (OPTIONAL MATCH)

AlexPresso opened this issue · 10 comments

I'm trying to execute the following query:

func FindUserFusionNetwork(sess gogm.SessionV2, discordTag string) (fusions []structures.Fusion) {
	query := `MATCH (i:Item)-[fr:FUSION_INPUT|FUSION_RESULT]-(f:Fusion) ` +
		`OPTIONAL MATCH (u:User{discordUsername: $discordTag})-[ui:INVENTORY_ITEM]->(i) ` +
		`RETURN *`
	err = sess.Query(context.Background(), query, map[string]interface{}{"discordTag": discordTag}, &fusions)
        fmt.Println(err)
	return
}

While it works perfectly in the Neo4J Browser, gogm (v2) seems unable to extract the requested structure from the resultset.
Am I doing something wrong ?

Edit: It returns the following error: failed auto read tx, label not found for node [1281], gogm: internal error, but the node having id = 1281 is an Item node, shouldn't it hydrate the Fusion structure based on it ?.

Did you register Item when you initialized gogm? Also, gogm expects a slice of pointers. It looks like the slice of Fusion being passed in is a normal slice.

Oh yes, you are right, I'm fixing the pointer, thanks.
Yes, Item and all needed structures are initialized at startup:

func Init() {
	config := gogm.Config{
		IndexStrategy: gogm.IGNORE_INDEX,
		PoolSize:      viper.GetInt("db.poolSize"),
		Port:          viper.GetInt("db.port"),
		Host:          viper.GetString("db.host"),
		Password:      viper.GetString("db.password"),
		Username:      viper.GetString("db.username"),
		Protocol:      "bolt",
	}

	_gogm, err := gogm.New(
		&config,
		gogm.DefaultPrimaryKeyStrategy,
		&structures.Item{},
		&structures.Fusion{},
		&structures.User{},
		&structures.InventoryItem{},
	)

	if err != nil {
		log.Fatal(err)
	}

	gogm.SetGlobalGogm(_gogm)
}

Did that fix the issue?

No, it's still giving that error

I'm wondering if its getting confused with return *. I'm going to write a test to see if I can reproduce this and get back to you.

@erictg should the current version of GOGM support queries that do not return paths (as in this issue)?
I thought it supports paths only and can also handle requests that return a node.

From my experience.
Without paths GOGM can processed queries that return just a node. Something like this:

MATCH (n)-[..]-(..) WHERE ... RETURN n

But when you need relations and nodes, you need to use paths.
From my code, such query doesn't work (same with RETURN *):

MATCH (object{twinId:"..."})-[r:IS_DESCRIBED_BY]->(value:ReferenceInformationObject{twinId:".."})
WHERE value.name in [...] RETURN object,r,value

But paths GOGM process correctly:

MATCH p=(object{twinId:"..."})-[r:IS_DESCRIBED_BY]->(value:ReferenceInformationObject{twinId:"..."})
WHERE value.name in [...] RETURN p

In my code, I always use paths for GOGM queries. Without returning paths, GOGM does not work.

Yes, but that means you can only match one and only path per query, It's impossible to use OPTIONAL MATCH in a single path.
It's also the same when you want to use UNION.

@AlexPresso you can use an OPTIONAL MATCH in a single path using the following syntax:

MATCH p=(n:SomeNode)-[..]-(..) WHERE ... RETURN p
UNION ALL OPTIONAL MATCH p=(n)-[..]-(..) RETURN p

@AlexPresso I believe that the bug that spawned the original discussion behind this issue is also solved by some of the changes I made to the decoder in #82. We're close to merging it now, but could you let me know if this bug (failed auto read tx, label not found for node...) is solved by these changes?

Please report back if the problem persists :)