无法删除Solr键

ale*_*ale 2 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>
Run Code Online (Sandbox Code Playgroud)

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

<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>
Run Code Online (Sandbox Code Playgroud)

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

任何见解?

Tom*_*lak 7

经过大量的调试我发现了.

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

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

我们假设:

  • /path/to/file你的系统上有一个调用的文件
  • 它在Solr集合中编入索引foo.

当您发出a时<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>
Run Code Online (Sandbox Code Playgroud)

这是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>
Run Code Online (Sandbox Code Playgroud)

咦?身份证中不应该有号码吗?

事实证明,Adobe的某些人认为将数字用于索引文件的唯一ID是一个快乐的聪明主意,嗯,节省空间,我想.

但是由于某些莫名其妙的原因,只有在有问题的文件仍然存在时才会发生这种情况.如果它不存在,ColdFusion将注意并传递路径.

检查数字表明它适合32位有符号整数值.(我已经检查过,uid集合领域有很多负面价值.)

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

Java中的等一应俱全,32位散列是... java.lang.Object.hashCode().

答对了.

"/path/to/file".hashCode() // -> 1247603285
Run Code Online (Sandbox Code Playgroud)

因此解决方案是永远不要通过其路径删除文件,但始终如下:

<cfindex collection="foo" action="delete" key="#path.hashCode()#">
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

快点

<cfsearch collection="foo" name="foo">
Run Code Online (Sandbox Code Playgroud)

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


Eric Lippert解释了对象哈希码以及为什么在应用程序中将它们用于任何"实用"是一个坏主意它是一篇.NET文章,但也适用于Java.

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


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

  • 谢谢你的呐喊.您可能也对本文感兴趣:http://blogs.msdn.com/b/ericlippert/archive/2005/10/24/482447.aspx (2认同)