2012-01-30 23 views
3

我试图把使用Ruby on Rails 3的“电影搜索”应用程序放在一起。我使用SPARQL(RDF和sparql/client)从dbpedia提取数据。我想要一个潜在的用户能够搜索电影,查看结果,然后单击查看我在该电影上生成的包含更多信息(来自dbpedia和我自己的本地数据库)的页面。这是一个在我的使用dbpedia和SPARQL的Rails应用程序中实现搜索功能的好方法吗?有一个更好的方法吗?

这是我第一次使用庞大的数据集和SPARQL,我注意到它非常慢,我想这是无法帮助的。尽管如此,我仍然非常希望将它用作数据源。

我有我的Rails应用程序设置使用MongoDB,所以我想我可以利用它来缓存一些DBPedia数据,因此用户不需要等待每一次查询。不过,我坚持实施这样的最佳方式。我现在的想法是这些方针的东西:

在第一次搜索过,我存储每个结果的详细信息在我的本地数据库(可能是基本的电影信息,如标题,概述,今年,替代标题)

当用户执行搜索时,会出现以下情况:

  1. 运行在我的本地数据库搜索查询来获取相关的存储电影(搜索标题和概要只,最有可能的)。如果在过去的X天内电影还没有从dbpedia中更新,我不会包含它。
  2. 快速向用户显示那些相关的本地结果并制作这些电影的列表。
  3. 当用户查看存储的结果时,会查询dbpedia。从这个查询结果中,我创建了DBpedia相关结果的列表。
  4. 我从dbpedia查询结果集中删除了任何已在初始本地结果集中的影片,以防止用户看到重复的结果。
  5. 我在本地结果下面显示剩余的dbpedia查询结果,并将每个新的非存储结果保存在本地数据库中(包括last_updated时间,并根据需要更新任何现有的本地项目)。
  6. 当用户点击一个电影页面时,dbpedia的基本信息和我存储的额外信息已经存储在本地,并且可以在页面上快速提取,但更高级的信息(导演,语言,位置,链接到相关网站)在加载时从dbpedia查询。我显示在检索新信息时在不同部分加载对话框等。

我的想法做一些像上面这样用户就可以很快看到一些结果,而其余结果得到来自DBpedia中加载的,而我存储一些东西,但不是一个疯狂的金额。

但我想获得一些帮助,看它是否现实并且是否是一个好主意。我可以想象,首先搜索我的本地数据库可能会将用户的初始结果歪曲为之前搜索过的内容,并且如果他们特定的期望的电影(如果他们放入标题中)在未显示之前未进行搜索在列表中。在本地存储相关数据集(即所有电影)的副本并根据需要更新它会更有意义吗?那太多了吧?

无论如何,我真的很感激一些建议,尽可能为用户提供尽可能无缝的东西,同时仍然处于理智的界限之内。提前致谢!

编辑:这是我正在使用的测试搜索查询的代码。我以为我正在测试中超级超级基础...但它超时lot

query = " 
    PREFIX owl: <http://www.w3.org/2002/07/owl#> 
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
    PREFIX foaf: <http://xmlns.com/foaf/0.1/> 
    PREFIX dc: <http://purl.org/dc/elements/1.1/> 
    PREFIX : <http://dbpedia.org/resource/> 
    PREFIX dbpedia2: <http://dbpedia.org/property/> 
    PREFIX dbpedia: <http://dbpedia.org/> 
    PREFIX skos: <http://www.w3.org/2004/02/skos/core#> 
    PREFIX dbo: <http://dbpedia.org/ontology/> 

    SELECT ?subject ?label ?abstract ?runtime ?date ?name WHERE { 
    {?subject rdf:type <http://dbpedia.org/ontology/Film>} 
    UNION 
    {?subject rdf:type <http://dbpedia.org/ontology/TelevisionShow>}. 
    OPTIONAL {?subject dbo:runtime ?runtime}. 
    OPTIONAL {?subject dbo:releaseDate ?date}. 
    OPTIONAL {?subject foaf:name ?name}. 
    ?subject rdfs:comment ?abstract. 
    ?subject rdfs:label ?label. 
    FILTER((lang(?abstract) = 'en') && (lang(?label) = 'en') && REGEX(?label, '" + str + "')). 

    } 
    LIMIT 30 
" 
result = {} 
client = SPARQL::Client.new("http://dbpedia.org/sparql") 
result = client.query(query).each_binding { |name, value| puts value.inspect } 
return result 

回答

1

什么是您用来查询dbpeid的SPARQL查询?应该可以对此进行优化以提高性能。您还应该能够使用类别URI进行过滤。你也应该能够使用OFFSET和LIMIT预测来减少结果的数量。如果您正在使用全文搜索,那么您可能还会考虑使用特定于Virtuoso的'bif:contains'属性,因为正则表达式过滤器有点快,但缺点是非标准/ Virtuoso特定。另外,您还可以使用HTTP缓存来改进后续搜索结果(SPARQL协议通过HTTP运行并不令人惊讶)。

除此之外,您可以尝试简单地使用自己的三重存储并将每天晚上从dbpedia加载的电影加载到mongo数据库中。

EDITED基于提供查询的

好简单地通过反复试验,以下模式造成很大的问题:

?subject rdfs:comment ?abstract. 
    ?subject rdfs:label ?label. 
    FILTER((lang(?abstract) = 'en') && (lang(?label) = 'en') && REGEX(?label, '" + str + "')). 

过滤器可能会很慢,但即使没有过滤器的查询超时。我会更关心可选的条款(可选可以很慢)。尝试它没有。您可能需要为摘要和标签运行单独的查询。

+0

嗨,谢谢你的回应!我为我正在使用的示例查询添加了一些代码,只是使用基本的正则表达式来测试一个字符串,但是在我重新测试它的时候,我注意到当它试图用一个简单的字符串。我现在会研究你的其他建议。谢谢! – Sarah 2012-01-31 04:40:18

相关问题