How Gremlin query same sql like for search feature

前端 未结 7 928
栀梦
栀梦 2020-12-31 15:12

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

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

I\'ve check

相关标签:
7条回答
  • 2020-12-31 15:15

    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
    
    0 讨论(0)
  • 2020-12-31 15:19

    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.

    0 讨论(0)
  • 2020-12-31 15:30

    For Cosmos Db Gremlin support

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

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

    0 讨论(0)
  • 2020-12-31 15:31

    Try:

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

    or

    g.V().filter({ it.getProperty("foo").contains("search") })
    
    0 讨论(0)
  • 2020-12-31 15:33

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-31 15:36

    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/

    0 讨论(0)
提交回复
热议问题