Exemple #1
0
func getFrequencyRelations(db *neoism.Database, r *model.Relationship, t *testing.T) int {
	res := []struct {
		Frequency int `json:"frequency"`
	}{}

	cq := neoism.CypherQuery{
		Statement: fmt.Sprintf(
			`
            	MATCH (subject:%[1]s)-[r:%[2]s]->(object:%[3]s)
            	WHERE subject.id = {subjectId} AND object.id = {objectId}
            	RETURN r.frequency as frequency
            `,
			util.UpperCaseFirst(r.Subject), strings.ToUpper(r.Relationship),
			util.UpperCaseFirst(r.Object),
		),
		Parameters: neoism.Props{"subjectId": r.SubjectID, "objectId": r.ObjectID},
		Result:     &res,
	}
	if err := db.Cypher(&cq); err != nil {
		assert.Fail(t, "Unexpected error: "+err.Error())
		return -1
	}

	if len(res) > 0 {
		return res[0].Frequency
	}
	return -1
}
Exemple #2
0
// GetOrCreateNode returns a Node, creates one if it does not exist. This method
// overrides the neoism one as there is a bug
func GetOrCreateNode(db *neoism.Database, label, key string, p neoism.Props) (n *neoism.Node, created bool, err error) {
	node, created, err := db.GetOrCreateNode(util.UpperCaseFirst(label), key, p)
	// due to a bug in neoism, label is not added
	// see: https://github.com/jmcvetta/neoism/issues/62
	if created {
		node.AddLabel(util.UpperCaseFirst(label))
	}
	return node, created, err
}
Exemple #3
0
// DeleteRelationship deletes a relationship
func DeleteRelationship(db *neoism.Database, r *model.Relationship) error {
	cq := neoism.CypherQuery{
		Statement: fmt.Sprintf(
			`
                MATCH (a:%s)-[r:%s]->(b:%s)
                WHERE a.id = {subjectId} AND b.id = {objectId}
                DELETE r
            `,
			util.UpperCaseFirst(r.Subject), strings.ToUpper(r.Relationship),
			util.UpperCaseFirst(r.Object),
		),
		Parameters: neoism.Props{
			"subjectId": r.SubjectID, "objectId": r.ObjectID,
		},
	}
	return db.Cypher(&cq)
}
Exemple #4
0
// CreateOrIncRelationship creates a relationship or increments a property if it
// already exists
func CreateOrIncRelationship(db *neoism.Database, r *model.Relationship) error {
	cq := neoism.CypherQuery{
		Statement: fmt.Sprintf(
			`
			MATCH (a:%s), (b:%s)
			WHERE a.id = {subjectId} AND b.id = {objectId}
			CREATE UNIQUE (a)-[r:%s]->(b)
			SET r.frequency = COALESCE(r.frequency, 0) + 1
			`,
			util.UpperCaseFirst(r.Subject), util.UpperCaseFirst(r.Object),
			strings.ToUpper(r.Relationship),
		),
		Parameters: neoism.Props{
			"subjectId": r.SubjectID, "objectId": r.ObjectID,
		},
	}
	return db.Cypher(&cq)
}
Exemple #5
0
// GetRecommendations returns a list of recommended IDs
func GetRecommendations(rq *model.RecommendationRequest) (*model.Recommendation, error) {
	// connect to graph
	db := GetGraph()

	res := []struct {
		ID     string  `json:"object.id"`
		Weight float32 `json:"weight"`
	}{}

	cq := neoism.CypherQuery{
		Statement: fmt.Sprintf(
			// Currently we are using only COUNT
			// Since we store the number of times the relational event happened
			// We could have used SUM(r), however that is not useful for the
			// current use cases (a customer may view a product many times and
			// skew the results)
			`
				MATCH (subject:%[1]s)-[:%[2]s]->(%[3]s)<-[:%[2]s]-(%[1]s)-[r:%[2]s]->(object:%[3]s)
				WHERE subject.id = {subjectId} AND NOT((subject)-[:%[2]s]->(object))
				RETURN object.id, COUNT(r) AS weight
				ORDER BY weight DESC
				LIMIT %[4]d
		  `,
			util.UpperCaseFirst(rq.Subject), strings.ToUpper(rq.Relationship),
			util.UpperCaseFirst(rq.Object), rq.Limit,
		),
		Parameters: neoism.Props{"subjectId": rq.SubjectID},
		Result:     &res,
	}
	if err := db.Cypher(&cq); err != nil {
		return nil, err
	}

	recommendation := model.NewRecommendation()
	for _, result := range res {
		recommendation.Add(result.ID, result.Weight)
	}
	return recommendation, nil
}