无法删除Solr键

时间:2012-05-30 13:38:16

标签: coldfusion solr

无法从Solr集合中删除文件中的密钥。

使用以下方法更新Solr集合:

<cfoutput query="fileQuery">
  <cfset theFile = defaultpath & "#fileID#.pdf" />

  <cfif fileExists(theFile)>
    <cfindex
      action="update"
      collection="file_vault_solr"
      type="file"
      key="#theFile#"
      title="#documentName#"
      body="fileNumber,documentName"
      custom1="/filevault/#filealias#"
      custom2="#fileNumber#"
      custom3="#documentName#"
    >
  </cfif>
</cfoutput>

但是,当尝试从目录中删除密钥时,它根本不起作用。这是用于(尝试)删除密钥的代码:

<cfoutput query="deletedFile">
  <cfset theFile = defaultpath & "#fileID#.pdf" />

  <!--- Remove the deleted file from the collection. --->
  <cfindex
    collection="file_vault_solr"
    type="file"
    action="Delete"
    key="#theFile#"
  >
</cfoutput>

但是,密钥不会被删除。唯一有效的方法是清除整个目录并重新索引所有文档。

任何见解?

3 个答案:

答案 0 :(得分:7)

经过大量调试后我发现了。

这种行为的原因是......呃......不幸的......呃......“设计决策”Adobe在实现ColdFusion和Solr之间的接口时采取了这种决定。

因此,您拥有索引文件的Solr集合,并希望有选择地清除磁盘上不再存在的文件。我很确定你所处的确切情况。

我们假设:

  • 您的系统上有一个名为/path/to/file的文件,
  • 它在Solr集合foo中编入索引。

当您发出<cfindex collection="foo" action="delete" key="/path/to/file">时,ColdFusion会向Solr发送以下HTTP请求:

POST /solr/foo/update?wt=xml&version=2.2 (application/xml; charset=UTF-8)
<delete><id>1247603285</id></delete>

这是Solr很乐意履行的完全合理的要求。唯一奇怪的是<id>中的数字。在任何情况下,该操作后文件将从索引中消失。

重新索引文件并将其从磁盘中删除。现在:

  • 您的系统上不再有名为/path/to/file的文件,但
  • 仍然索引在Solr集合foo中。

让我们再次执行相同的<cfindex action="delete">操作。

POST /solr/foo/update?wt=xml&version=2.2 (application/xml; charset=UTF-8)
<delete><id>/path/to/file</id></delete>

咦? ID中不应该有数字吗?

事实证明,Adobe的某些人认为将数字用于索引文件的唯一ID是一个非常明智的想法,呃,节省空间,我想。

然而由于一些莫名其妙的原因,只有当相关文件仍然存在时才会发生这种情况。如果它不存在,ColdFusion将注意并传递路径。

检查数字表明它适合32位有符号整数值。 (我已经检查过,集合的uid字段中有很多负值。)

所以这看起来好像他们使用某种哈希算法返回32位并将其放入int中。 CRC32让人想起,但事实并非如此。此外,java.util.zip.CRC32会返回long,因此首先不会出现任何负值。

Java中另一个随时可用的32位哈希值是...... java.lang.Object.hashCode()

宾果。

"/path/to/file".hashCode() // -> 1247603285

所以解决办法是永远不要按路径删除文件,但总是这样:

<cfindex collection="foo" action="delete" key="#path.hashCode()#">

对于不再存在的文件,这是正确的。

更重要的是:对于仍然存在的文件,这也是正确的 - ColdFusion无论如何都会发送哈希码。

在Adobe修复此问题之前,这是一种安全且简单的解决方法。

请注意,文件路径区分大小写,并且必须与索引中存储的路径完全匹配。

快速

<cfsearch collection="foo" name="foo">

没有任何criteria将返回所有索引条目,因此检索孤立条目的确切路径不是一个大问题。


Eric Lippert explains object hash codes and why it is a bad idea to use them for anything "practical" in an application这是一篇.NET文章,但也适用于Java。

归结为:Adobe应该将实际的路径存储在Solr集合中,并保留他们似乎尝试过Solr的性能优化。


我已经对Adobe的ColdFusion错误数据库提交了Bug 3589991

答案 1 :(得分:2)

密钥必须与Solr索引中的内容完全匹配。因此,请确保两者中的“defaultpath”相同,并检查案例是否匹配,因为我认为Solr区分大小写。

答案 2 :(得分:1)

要调试这个,我建议你将status =“myStatusVar”添加到cfindex调用中。然后在添加和删除上查看发生了什么。如果删除未返回“已删除计数”。然后是密钥不匹配。

<cfindex
collection="file_vault_solr"
type="file"
action="Delete"
key="#theFile#"
status="myStatusVar"
>