Frage

Im using OrientDB type graph. I need syntax of Gremlin for search same SQL LIKE operator

LIKE 'search%' or LIKE '%search%'

I've check with has and filter (in http://gremlindocs.com/). However it's must determine exact value is passed with type property. I think this is incorrect with logic of search.

Thanks for anything.

War es hilfreich?

Lösung 2

Try:

g.V().filter({ it.getProperty("foo").startsWith("search") })

or

g.V().filter({ it.getProperty("foo").contains("search") })

Andere Tipps

For Cosmos Db Gremlin support

g.V().has('foo', TextP.containing('search'))

You can find the documentation Microsoft Gremlin Support docs And TinkerPop Reference

You can use filter with a bit of regex:

gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.V.filter{it.name.matches(".*ark.*")}.name
==>marko

or with more Groovy syntactic sugar:

gremlin> g.V.filter{it.name==~/.*ark.*/}.name 
==>marko

The above answer (and the accepted answer) apply to TinkerPop 2.x and the following applies to 3.x which is the version currently in wide usage:

At this time TinkerPop 3.x does not support regex as part of the Gremlin core language, however regex may be available to the specific graph system you are using (DSE Graph, JanusGraph, etc) and those graphs will supply their own libraries to extend Gremlin with a regex predicate (and/or other search options like fuzzy and tokenizations). Consult the documentation of your graph for what is available.

A graph specific extension will be the most efficient way to do a regex based search as it will rely on internal indexing functions that are optimized to handle such things, but there are methods to do in-memory sorts of regex searches through closures which are similar to the TinkerPop 2.x answer above.

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().filter{it.get().value('name').matches(".*ark.*")}
==>v[1]

Since we're using a closure, we can place whatever Java (in this case Groovy) code we want in that function. Note that for it.get().value('name') the it is a Groovy notation that gets refers to the current Traverser in the stream of V() and it holds a Vertex object which is retrieved via get().

This approach will work wherever closures are accepted, but they don't work everywhere as not all graphs will support them. If you are not on the JVM (e.g. python) then you are likely submitting Gremlin scripts to a server or using bytecode based requests. If you are submitting scripts then you should be able to submit the request just as shown above. If you are using bytecode then you have to explicitly declare the lambda as a string in your traversal as shown here for Python.

Ultimately, use of closures/lambdas are not recommended as they reduce portability of your code, expose security holes, etc. If you need regex, it would be best to utilize a graph that has native support for them and a code library that contains the custom predicates specific to your programming language.

For people finding this answer here is an updated version of how you can search (very similar to the accepted answer)

For the gremlin console (gremlin.sh):

g.V().filter({ it.get().value("foo").contains("search") })

Also if you have your index backend being ElasticSearch (might work for other indexing backends as well) this works as well:

g.V().has("foo", Text.textContains("search"))

For JanusGraph with Gremlin Python (gremlin_python):

from gremlin_python.process.traversal import TextP
g.V().has('foo', TextP.containing('search'))

Source: https://docs.janusgraph.org/index-backend/text-search/

As one of the committers of the SimpleGraph project i know of the solution implemented in that project

https://github.com/BITPlan/com.bitplan.simplegraph/blob/master/simplegraph-core/src/main/java/com/bitplan/gremlin/RegexPredicate.java

Example

g().V().has("tosearch", RegexPredicate.regex("search.*"))

RegexPredicate

import java.util.function.BiPredicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.tinkerpop.gremlin.process.traversal.P;

// https://groups.google.com/forum/#!topic/gremlin-users/heWLwz9xBQc
// https://stackoverflow.com/a/45652897/1497139
public class RegexPredicate implements BiPredicate<Object, Object> {
    Pattern pattern = null;
    private Mode mode;

    enum Mode {
        FIND, MATCH
    }

    public RegexPredicate(String regex, Mode mode) {
        this.mode = mode;
        pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
    };

    public RegexPredicate(String regex) {
        this(regex,Mode.FIND);
    }

    @Override
    public boolean test(final Object first, final Object second) {
        String str = first.toString();
        Matcher matcher = pattern.matcher(str);
        switch (mode) {
        case FIND:
            return matcher.find();
        case MATCH:
            return matcher.matches();
        }
        return false;
    }

    /**
     * get a Regular expression predicate
     * 
     * @param regex
     * @return - the predicate
     */
    public static P<Object> regex(Object regex) {
        BiPredicate<Object, Object> b = new RegexPredicate(regex.toString());
        return new P<Object>(b, regex);
    }
}

I know I'm way late on this, but I was trying to figure this out as well and hope it helps someone out there. This is implemented in Java. TinkerPop version 3.2.5. I have no idea how to do this without writing some Java.

1) Create an enum that implements BiPredicate. (Note, this predicate allows wildcards and is case insensitive.)

public enum StringCompare implements BiPredicate<Object, Object> {
wildcard {
        @Override
        public boolean test(final Object first, final Object second) {

            String str = first.toString();
            String regex = second.toString();

            Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(str);

            return matcher.matches();
        }
    }
}

2) Create your regular expression following the Java rules. I found this link pretty helpful. http://www.developer.com/java/data/using-java-regular-expressions.html

3) Use the has() method, pass it the property key, and create a new P object.

String regex = "Mar.*"; //2
GraphTraversal<Vertex,Vertex> gtv = g.V().has("name", new P<>(StringCompare.wildcard, regex)); //3
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top