shaharnakash
shaharnakash

Reputation: 675

c# neo4j cypher use regular exp

I'm using the Neo4j graph DB with Neo4jClient and I'm trying to execute a search query on nodes, where the result should return a list of nodes that contain a given query string.

I have this working, but it seems inefficient as I'm bringing all the Groups back and then filtering. Is there a better way?

    internal object SearchGroups(string query)
    {
        var groups = WebApiConfig.GraphClient.Cypher
            .Match("(g:Groups)")
            .Return(g => g.As<Groups>())
            .Results;
        List<Groups> groupList = new List<Groups>();
        foreach (var item in groups)
        {
            if (item.GroupName.Contains(query))
            {
                groupList.Add(item);
            }
        }
        return groupList;
    }

I've seen examples that filter using .Where((Groups g)=> g.GroupName == query) but this only returns if it matches, not if it Contains.

Upvotes: 0

Views: 337

Answers (1)

Charlotte Skardon
Charlotte Skardon

Reputation: 6280

Well, you're mostly there with the tag of regex - you have 2 options depending on what you want to do, and what your query is. First though - Please read the documentation for Cypher and try your queries out in the Admin window (localhost:7474) first, you'll find it hugely beneficial. In particular for this the Where documentation would have helped you a lot.

Option 1: Regex

var groups = WebApiConfig.GraphClient.Cypher
    .Match("(g:Groups)")
    .Where("g.GroupName =~ {nameParam}")
    .WithParam("nameParam", string.Format(".*{0}.*", query))
    .Return(g => g.As<Groups>())
    .Results;

Cypher for this looks like:

MATCH (g:Groups) WHERE g.GroupName =~ '.*<your query text>.*' RETURN g

This is using a regex - as a parameter which will work in the same way as Contains. Using regex like this is not performant, and it might be better if you can do something like....

Option 2: Starts With

This is only applicable if you're using Neo4j 2.3+ and your query is a Starts With type query, but would be significantly faster.

var groups = WebApiConfig.GraphClient.Cypher
    .Match("(g:Groups)")
    .Where((Groups g) => g.GroupName.StartsWith(query))
    .Return(g => g.As<Groups>())
    .Results;

Cypher for this looks like:

MATCH (g:Groups) WHERE g.GroupName STARTS WITH <your query text> RETURN g

PS

You really should return IEnumerable<Groups>/ICollection<Groups>/IList<Groups> from your method instead of object, and you could also replace your foreach with:

var groupsList = groups.Where(g => g.GroupName.Contains(query)).ToList();

Or just return it:

return groups.Where(/*see above*/);

Upvotes: 1

Related Questions