跳到内容

搜索谓词和混合索引数据类型

本页列出了 JanusGraph 在全局图搜索和局部遍历中支持的所有比较谓词。

注意

本节的某些部分需要混合索引,请参见混合索引后端

比较谓词

Compare 枚举指定了以下用于索引查询构建和上述示例中使用的比较谓词

  • eq (等于)
  • neq (不等于)
  • gt (大于)
  • gte (大于或等于)
  • lt (小于)
  • lte (小于或等于)

所有比较谓词都支持 String、数值、Date 和 Instant 数据类型。Boolean 和 UUID 数据类型支持 eqneq 比较谓词。

eqneq 可用于 Boolean 和 UUID。

文本谓词

Text 枚举指定了用于查询匹配文本或字符串值的文本搜索。我们区分两种类型的谓词

  • 文本搜索谓词,它们在文本字符串被分词后,匹配文本字符串中的单个词。这些谓词不区分大小写。
    • textContains:如果文本字符串中(至少)有一个词与查询字符串匹配,则为 true
    • textNotContains:如果文本字符串中没有词与查询字符串匹配,则为 true
    • textContainsPrefix:如果文本字符串中(至少)有一个词以查询字符串开头,则为 true
    • textNotContainsPrefix:如果文本字符串中没有词以查询字符串开头,则为 true
    • textContainsRegex:如果文本字符串中(至少)有一个词与给定的正则表达式匹配,则为 true
    • textNotContainsRegex:如果文本字符串中没有词与给定的正则表达式匹配,则为 true
    • textContainsFuzzy:如果文本字符串中(至少)有一个词与查询字符串相似(基于 Levenshtein 编辑距离),则为 true
    • textNotContainsFuzzy:如果文本字符串中没有词与查询字符串相似(基于 Levenshtein 编辑距离),则为 true
    • textContainsPhrase:如果文本字符串包含查询字符串中的精确词序列,则为 true
    • textNotContainsPhrase:如果文本字符串不包含查询字符串中的词序列,则为 true
  • 字符串搜索谓词,它们匹配整个字符串值
    • textPrefix:如果字符串值以给定的查询字符串开头
    • textNotPrefix:如果字符串值不以给定的查询字符串开头
    • textRegex:如果字符串值完全匹配给定的正则表达式
    • textNotRegex:如果字符串值不完全匹配给定的正则表达式
    • textFuzzy:如果字符串值与给定的查询字符串相似(基于 Levenshtein 编辑距离)
    • textNotFuzzy:如果字符串值与给定的查询字符串不相似(基于 Levenshtein 编辑距离)

有关全文和字符串搜索的更多信息,请参阅文本搜索

地理谓词

Geo 枚举指定了地理位置谓词。

  • geoIntersect 如果两个几何对象至少有一个共同点,则为 true(与 geoDisjoint 相反)。
  • geoWithin 如果一个几何对象包含另一个几何对象,则为 true。
  • geoDisjoint 如果两个几何对象没有共同点,则为 true(与 geoIntersect 相反)。
  • geoContains 如果一个几何对象被另一个几何对象包含,则为 true。

有关地理搜索的更多信息,请参阅地理映射

查询示例

以下查询示例演示了教程图上的一些谓词。

// 1) Find vertices with the name "hercules"
g.V().has("name", "hercules")
// 2) Find all vertices with an age greater than 50
g.V().has("age", gt(50))
// or find all vertices between 1000 (inclusive) and 5000 (exclusive) years of age and order by ascending age
g.V().has("age", inside(1000, 5000)).order().by("age", asc)
// which returns the same result set as the following query but in reverse order
g.V().has("age", inside(1000, 5000)).order().by("age", desc)
// 3) Find all edges where the place is at most 50 kilometers from the given latitude-longitude pair
g.E().has("place", geoWithin(Geoshape.circle(37.97, 23.72, 50)))
// 4) Find all edges where reason contains the word "loves"
g.E().has("reason", textContains("loves"))
// or all edges which contain two words (need to chunk into individual words)
g.E().has("reason", textContains("loves")).has("reason", textContains("breezes"))
// or all edges which contain words that start with "lov"
g.E().has("reason", textContainsPrefix("lov"))
// or all edges which contain words that match the regular expression "br[ez]*s" in their entirety
g.E().has("reason", textContainsRegex("br[ez]*s"))
// or all edges which contain words similar to "love"
g.E().has("reason", textContainsFuzzy("love"))
// 5) Find all vertices older than a thousand years and named "saturn"
g.V().has("age", gt(1000)).has("name", "saturn")

数据类型支持

虽然 JanusGraph 的复合索引支持可以存储在 JanusGraph 中的任何数据类型,但混合索引仅限于以下数据类型。

  • Byte
  • 短整型
  • 整数
  • 长整数
  • Float
  • 双精度浮点数
  • 字符串
  • Geoshape
  • Date
  • Instant
  • UUID

未来将支持更多数据类型。

Geoshape 数据类型

Geoshape 数据类型支持表示点、圆、框、线、多边形、多点、多线和多多边形。索引后端目前支持索引点、圆、框、线、多边形、多点、多线、多多边形和几何集合。地理空间索引查找仅通过混合索引支持。

要构建 Geoshape,请使用以下方法

 //lat, lng
Geoshape.point(37.97, 23.72)
//lat, lng, radius in km
Geoshape.circle(37.97, 23.72, 50)
//SW lat, SW lng, NE lat, NE lng
Geoshape.box(37.97, 23.72, 38.97, 24.72)
//WKT
Geoshape.fromWkt("POLYGON ((35.4 48.9, 35.6 48.9, 35.6 49.1, 35.4 49.1, 35.4 48.9))")
//MultiPoint
Geoshape.geoshape(Geoshape.getShapeFactory().multiPoint().pointXY(60.0, 60.0).pointXY(120.0, 60.0)
  .build())
//MultiLine
Geoshape.geoshape(Geoshape.getShapeFactory().multiLineString()
  .add(Geoshape.getShapeFactory().lineString().pointXY(59.0, 60.0).pointXY(61.0, 60.0))
  .add(Geoshape.getShapeFactory().lineString().pointXY(119.0, 60.0).pointXY(121.0, 60.0)).build())
//MultiPolygon
Geoshape.geoshape(Geoshape.getShapeFactory().multiPolygon()
  .add(Geoshape.getShapeFactory().polygon().pointXY(59.0, 59.0).pointXY(61.0, 59.0)
    .pointXY(61.0, 61.0).pointXY(59.0, 61.0).pointXY(59.0, 59.0))
  .add(Geoshape.getShapeFactory().polygon().pointXY(119.0, 59.0).pointXY(121.0, 59.0)
    .pointXY(121.0, 61.0).pointXY(119.0, 61.0).pointXY(119.0, 59.0)).build())
//GeometryCollection
Geoshape.geoshape(Geoshape.getGeometryCollectionBuilder()
  .add(Geoshape.getShapeFactory().pointXY(60.0, 60.0))
  .add(Geoshape.getShapeFactory().lineString().pointXY(119.0, 60.0).pointXY(121.0, 60.0).build())
  .add(Geoshape.getShapeFactory().polygon().pointXY(119.0, 59.0).pointXY(121.0, 59.0)
    .pointXY(121.0, 61.0).pointXY(119.0, 61.0).pointXY(119.0, 59.0).build()).build())

此外,通过 GraphSON 导入图时,几何体可以由 GeoJSON 表示

"37.97, 23.72"
[37.97, 23.72]
{
    "type": "Feature",
    "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
    },
    "properties": {
    "name": "Dinagat Islands"
    }
}
{
    "type": "Point",
    "coordinates": [125.6, 10.1]
}

GeoJSON 可以指定为 Point、Circle、LineString 或 Polygon。多边形必须是闭合的。请注意,与 JanusGraph API 不同,GeoJSON 将坐标指定为经纬度。

集合

如果您使用Elasticsearch,则可以索引具有 SET 和 LIST 基数的属性。例如

mgmt = graph.openManagement()
nameProperty = mgmt.makePropertyKey("names").dataType(String.class).cardinality(Cardinality.SET).make()
mgmt.buildIndex("search", Vertex.class).addKey(nameProperty, Mapping.STRING.asParameter()).buildMixedIndex("search")
mgmt.commit()
//Insert a vertex
person = graph.addVertex()
person.property("names", "Robert")
person.property("names", "Bob")
graph.tx().commit()
//Now query it
g.V().has("names", "Bob").count().next() //1
g.V().has("names", "Robert").count().next() //1