我正在使用OrientDB类型图。我需要Gremlin的语法来搜索相同的SQL LIKE运算符
LIKE 'search%' or LIKE '%search%'
我已检查过has和filter(在http://gremlindocs.com/中)。但是必须确定使用type属性传递的确切值。我认为这与搜索逻辑不一致。
感谢您的一切。
答案 0 :(得分:5)
尝试:
g.V().filter({ it.getProperty("foo").startsWith("search") })
或
g.V().filter({ it.getProperty("foo").contains("search") })
答案 1 :(得分:5)
获得Cosmos Db Gremlin的支持
g.V().has('foo', TextP.containing('search'))
答案 2 :(得分:2)
你可以使用filter
和一些正则表达式:
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.V.filter{it.name.matches(".*ark.*")}.name
==>marko
或更多Groovy语法糖:
gremlin> g.V.filter{it.name==~/.*ark.*/}.name
==>marko
上述答案(以及接受的答案)适用于TinkerPop 2.x,以下适用于3.x ,这是目前广泛使用的版本:
此时TinkerPop 3.x不支持正则表达式作为Gremlin核心语言的一部分,但是正则表达式可能适用于您正在使用的特定图形系统(DSE Graph,JanusGraph等),这些图表将提供自己的库使用正则表达式谓词(和/或其他搜索选项,如模糊和标记化)来扩展Gremlin。有关可用内容,请参阅图表文档。
特定于图形的扩展将是进行基于正则表达式的搜索的最有效方式,因为它将依赖于针对此类事物进行优化的内部索引函数,但是有一些方法可以通过闭包进行内存中的正则表达式搜索这与上面的TinkerPop 2.x答案类似。
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().filter{it.get().value('name').matches(".*ark.*")}
==>v[1]
由于我们正在使用闭包,我们可以在该函数中放置我们想要的任何Java(在本例中为Groovy)代码。请注意,对于it.get().value('name')
,it
是一个Groovy表示法,它引用Traverser
流中的当前V()
并且它包含一个Vertex
对象,通过get()
检索。
这种方法适用于接受闭包的任何地方,但它们无法在任何地方使用,因为并非所有图形都支持它们。如果您不在JVM(例如python)上,那么您可能会将Gremlin脚本提交给服务器或使用基于字节码的请求。如果您要提交脚本,那么您应该能够提交请求,如上所示。如果您正在使用字节码,则必须在遍历中将lambda显式声明为字符串,如图所示为here。
最终,建议不要使用闭包/ lambda,因为它们会降低代码的可移植性,暴露安全漏洞等。如果需要正则表达式,最好使用对它们具有原生支持的图形和代码库包含特定于您的编程语言的自定义谓词。
答案 3 :(得分:2)
对于找到此答案的人,这里是您如何搜索的更新版本(与接受的答案非常相似)
对于gremlin控制台(gremlin.sh):
g.V().filter({ it.get().value("foo").contains("search") })
此外,如果您的索引后端是ElasticSearch(也可能适用于其他索引后端),那么它也可以工作:
g.V().has("foo", Text.textContains("search"))
答案 4 :(得分:0)
我知道我在这方面已经很晚了,但我也想弄清楚这一点,并希望它可以帮助那些人。这是用Java实现的。 TinkerPop版本3.2.5。如果不编写Java,我不知道如何做到这一点。
1)创建一个实现BiPredicate的枚举。 (注意,此谓词允许使用通配符,并且不区分大小写。)
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)按照Java规则创建正则表达式。我发现此链接非常有用。 http://www.developer.com/java/data/using-java-regular-expressions.html
3)使用has()方法,传递属性键,并创建一个新的P对象。
String regex = "Mar.*"; //2
GraphTraversal<Vertex,Vertex> gtv = g.V().has("name", new P<>(StringCompare.wildcard, regex)); //3
答案 5 :(得分:0)
作为SimpleGraph项目的提交者之一,我知道该项目中实施的解决方案
示例强>
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);
}
}