2

从文件的 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>

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

有什么见解吗?

4

3 回答 3

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>

这是一个完全合理的要求,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>

嗯?身份证上不应该有数字吗?

事实证明,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

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

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

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

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

在 Adob​​e 修复此问题之前,这是一个安全且简单的解决方法。

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

一个快速

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

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


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

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


我已经针对 Adob​​e 的 ColdFusion 错误数据库提交了错误 3589991 。

于 2013-07-03T19:16:04.093 回答
2

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

于 2012-05-30T14:08:26.597 回答
1

要对此进行调试,我建议您将 status="myStatusVar" 添加到 cfindex call 。然后在添加和删除上查看发生了什么。如果删除未返回已删除计数。然后是密钥不匹配。

<cfindex
collection="file_vault_solr"
type="file"
action="Delete"
key="#theFile#"
status="myStatusVar"
>
于 2012-05-30T17:13:05.670 回答