Reputation: 33
Very new to Neo4J and the .Net Neo4Jclient, but I'm trying to get a basic project up and running. Would anybody have some basic code or examples for adding nodes to the server with indexes, while allowing relationships between the same node types? The final goal of the project is to create a graph version of the Princeton Wordnet - http://wordnet.princeton.edu/
Initially I'm attempting to create a relationship between two nodes of the same type, call them Root Words. They should be related via a IS_SYNONYM relationship. The root nodes will need to be fully text indexed to allow searching. This "should" allow me to search for all synonyms of a given root word.
This is how I see the relationship:
(RootWord1, Type[A]) < ==:[IS_SYNONYM] == > (RootWord2, Type[A])
And these are the basic structures I've started with:
public class RootWord
{
[JsonProperty()]
public string Term { get; set; }
}
public class IsSynonym : Relationship
, IRelationshipAllowingSourceNode<RootWord>
, IRelationshipAllowingTargetNode<RootWord>
{
public const string TypeKey = "IS_SYNONYM";
public IsSynonym(NodeReference targetNode)
: base(targetNode){}
public IsSynonym(NodeReference targetNode, object data)
: base(targetNode, data){}
public override string RelationshipTypeKey
{
get { return TypeKey; }
}
}
I've been staring at this for a while now so any help is hugely appreciated, Thanks.
Upvotes: 1
Views: 803
Reputation: 6280
The below code will add a synonym to a rootword: (You'll probably want to check if your 'word' and 'synonym' is already in the db so you could just create a relationship)
public static void AddNodeToDb(IGraphClient graphClient, string index, RootWord word, RootWord synonym)
{
if (!graphClient.CheckIndexExists(index, IndexFor.Node))
{
var configuration = new IndexConfiguration { Provider = IndexProvider.lucene, Type = IndexType.fulltext };
graphClient.CreateIndex(index, configuration, IndexFor.Node);
}
var wordReference = graphClient.Create(word, null, GetIndexEntries(word, index));
var synonymReference = graphClient.Create(synonym, null, GetIndexEntries(synonym, index));
graphClient.CreateRelationship(wordReference, new IsSynonym(synonymReference));
Console.WriteLine("Word: {0}, Synonym: {1}", wordReference.Id, synonymReference.Id);
}
The 'GetIndexEntries' method gets the entries you'll want to put in the index for your object (RootWord), as you only have term, that's easy:
private static IEnumerable<IndexEntry> GetIndexEntries(RootWord rootWord, string indexName)
{
var indexKeyValues =
new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("term", rootWord.Term)
};
return new[]
{
new IndexEntry
{
Name = indexName,
KeyValues = indexKeyValues.Where(v => v.Value != null)
}
};
}
So, say you've entered 'Ace', 'Great' You can query (using Cypher) as:
START n=node(0)
MATCH n-[:IS_SYNONYM]->res
RETURN res
(assuming node 0 is your root word you want!) which will return the 'Great' node. At the same time, because we also created a fulltext index, you can search for the rootword using the following code:
public static void QueryTerms(IGraphClient gc, string query)
{
var result = gc.QueryIndex<RootWord>("synonyms", IndexFor.Node, "term:" + query).ToList();
if (result.Any())
foreach (var node in result)
Console.WriteLine("node: {0} -> {1}", node.Reference.Id, node.Data.Term);
else
Console.WriteLine("No results...");
}
Once you have those nodes, you can traverse the 'IS_SYNONYM' relationships to get to the actual synonyms.
Upvotes: 4