Sparql MarkLogic中三元组的通配符搜索

Sparql MarkLogic中三元组的通配符搜索,sparql,marklogic,Sparql,Marklogic,是否可以使用ctsquery对三元组执行通配符搜索 我在sparql中进行了尝试,得到了正确的结果,但查询速度非常慢 例如: PREFIX skos: <http://www.w3.org/2004/02/skos/core#> select ?iri where { ?iri skos:prefLabel ?prefLabel . filter (STRSTARTS(lcase(?prefLabel), 'soviet')) } limit 250 现在使用iri元素

是否可以使用
cts
query对三元组执行通配符搜索

我在
sparql
中进行了尝试,得到了正确的结果,但查询速度非常慢

例如:

PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
select ?iri
where {
   ?iri skos:prefLabel ?prefLabel .
   filter (STRSTARTS(lcase(?prefLabel), 'soviet'))
} limit 250
现在使用iri元素上的
cts:element值
并使用pref label上的
通配符cts:element值查询对其进行过滤
我将获得所有匹配的iri并将它们传递给sparql查询。通过这一点,我可以看到性能有了很大的提高

cts:element-values(xs:QName('iri'), (),(), cts:element-value-query(xs:QName('pref-label'), 'sov* *'))
我知道上述方法将消耗更多内存,但这很好,因为性能非常好:)

观察:在
sparql
中传递受试者时,它运行得非常快

比如:

前缀skos:
选择?iri
在哪里{
值?iri{前缀:12345前缀:12346前缀:12339前缀:12345}
?iri skos:prefLabel?prefLabel。
#应用过滤器
}限额250

此答案中列出了两种方法


试试这个:

sem:sparql(
  "PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
   select ?iri
   where {
      ?iri skos:prefLabel ?prefLabel .
      filter (STRSTARTS(lcase(?prefLabel), 'soviet'))
   } limit 250",
  (),
  (),
  sem:store("any", cts:element-query(xs:QName("sem:object"), cts:word-query("soviet*")))
)
注意“苏维埃”和“*”之间的空格。以下文件解释了原因:

请注意,cts:element值查询中值的文本内容与cts:word查询中的短语相同,其中短语是元素值。因此,任何通配符和/或词干规则都被视为短语。例如,如果查询启用通配符的元素值为“hello friend”,则“he*”的cts:element值查询将不匹配,因为通配符匹配不跨越单词边界,但“hello”的cts:element值查询将匹配。对“”的搜索将匹配,因为“*”通配符本身已定义为匹配该值。类似地,词干分析规则应用于每个术语,因此当为查询启用词干分析时,搜索“hello friends”将匹配,因为“friends”与“friend”匹配

您可能希望改用
cts:element-word-query

然后,我们可以使用
cts:search
上的
$expression
参数来确保只获得所需的三元组。请注意,这需要过滤。一旦有了三元组,我们就可以使用XPath获取主题,然后将它们传递给SPARQL查询

综上所述,我们得到:

let $query := cts:element-value-query(xs:QName("sem:object"), "soviet *")
let $subjects := cts:search(/sem:triples/sem:triple, $query)/sem:subject/fn:string()

$subjects
传递到SPARQL查询中,然后离开。这应该行得通;我剩下的问题是它是否比你开始时的速度快。我很想听听你的测试结果

如果没有全文索引,您在SPARQL中的大部分内容都会丢失,因为必须对中间结果进行完全扫描+筛选。Marklogic是否支持全文搜索功能?如果是这样,只需使用itok,
cts:contains
在SPARQL中本机工作。如果也可以使用
cts:search
,那么可以尝试使用XQuery表达式。我这里没有Marklogic服务器,XPath也可以通过
fn:
前缀,但是如果这里没有使用全文索引,检查字符串开头仍然会很昂贵。您是否使用托管或嵌入的三元组?托管三元组。这不应该是
“苏联*”
?一个带有cts:query的sem:store可以减少sparql引擎预先评估的三元组,从而提供大量的性能改进,但请注意不要排除可能需要的三元组。无法保证在MarkLogic“管理”三元组的情况下持久化哪些三元组。@dave感谢您的回复,但我不能使用“存储”,因为我还必须连接到其他三元组(正如您已经提到的),并且我必须在sparql中过滤其他一些谓词上的三元组。是否有其他方法,如使用
cts:search wildcarded
功能获取主题虹膜并在sparql查询中传递这些虹膜。@DixitSingla请参阅第二种方法above@DaveCassel我尝试了第二种方法。请查看“daves评论后更新”部分。
sem:sparql(
  "PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
   select ?iri
   where {
      ?iri skos:prefLabel ?prefLabel .
      filter (STRSTARTS(lcase(?prefLabel), 'soviet'))
   } limit 250",
  (),
  (),
  sem:store("any", cts:element-query(xs:QName("sem:object"), cts:word-query("soviet*")))
)
cts:element-value-query(xs:QName("sem:object"), "soviet *", "wildcarded")
let $query := cts:element-value-query(xs:QName("sem:object"), "soviet *")
let $subjects := cts:search(/sem:triples/sem:triple, $query)/sem:subject/fn:string()