Lucene / Solr:存储某些关键字的偏移信息

时间:2015-12-06 21:25:53

标签: solr lucene

我们正在使用Solr来存储带有关键字的文档;每个关键字都与文档中的范围相关联。

关键字是在将它们加载到Solr之前通过一些花哨的分析和/或手工工作生成的。关键字可以在文档中重复多次。另一方面,单个文档中相同字符串的不同实例可以使用不同的关键字进行连接。

例如,本文件

Bill studied The Bill of Rights last summer.

可以附带以下关键字(括号中有偏移量):

William Brown (0:4)
legal term (13:31)  
summer 2011 (32:43)

(显然在其他文件中,比尔可以引用比尔克林顿比尔盖茨。同样,去年夏天 >将在不同的文件中提及不同的年份。我们确实拥有所有文件的所有这些信息。)

我知道该文档可以有一个字段,比如 KEYWORD ,它将存储William Brown。然后,当我搜索William Brown时,我会得到上述文件。那部分很容易。

但我不知道如何存储William Brown与文字范围0:4对应的信息,因此我可以突出显示第一个Bill,而不是第二个。{/ p>

我以为我可以使用TermVectors,但我不确定是否/如何存储自定义偏移量。我认为这是一个相当普遍的情况...

编辑:编辑以明确 Bill 可以引用不同文档中的不同人/事物。

EDIT2:编辑以明确文档可以包含同音异义词(具有不同含义的相同字符串)。

2 个答案:

答案 0 :(得分:3)

默认情况下,Solr会在标记化后存储每个标记的开始/结束位置,例如使用StandardTokenizer。此信息在下划线索引上编码。您在此处描述的用例听起来很像unit game; interface uses countrxadj,countrx,reason,crt; implementation var health,ehealth: integer; var a2:String; var rand3,guess:Integer; begin ClrScr; ehealth:=5; health:=10; Repeat Randomize; rand3:=Random (1); writeln('YOUR HP:',health); writeln('ENEMY HP:',ehealth); write('Guess the number (1 or 2):'); Readln(guess); if (rand3+1) = guess then ehealth:=ehealth-1 else health:=health-1; ClrScr; until (ehealth = 0) or (health = 0); writeln('GAME OVER! The ',countryadj,' revolution for ',revreason,' has won! ',country,' is a happy place again.'); readln; end.

使用SynonymFilterFactory定义同义词时,例如:SynonymFilterFactory foo等效于bar,条形词添加到文本标记化时生成的令牌流中,它将具有与原始令牌相同的偏移信息。因此,例如,如果您的文本是:" foo非常棒",则术语foo将具有以下偏移信息foo => baz新的标记(start=0,end=3)将被添加到您的索引中(假设您在索引时使用bar(start=0,end=3)

SynonymFilterFactory

应用 text: foo is awesome start: 0 4 7 end: 3 6 13 后:

SynonymFilterFactory

因此,如果您使用 bar text: foo is awesome start: 0 4 7 end: 3 6 13 触发查询,则文档会匹配,但如果您使用foo作为查询,则文档也会匹配,因为bar令牌已添加bar

在您的特定情况下,您尝试完成多项同义词,这是一个难题,您可能需要比Solr的默认同义词过滤器更多的东西。检查OpenSourceConnections的人this post和Lucidworks的this other post(Solr / Lucene背后的公司)。这两个帖子应该提供额外的信息和每种方法的警告。

您是否需要获取存储的偏移量以供稍后处理?

答案 1 :(得分:3)

两个Q Monte

解决方案优点:

  • 使用源文档逻辑存储的注释
  • 不了解荧光笔实现或自定义Java荧光笔开发需要
  • 由于所有定制都发生在Solr之外,因此该解决方案应与未来的Solr版本向前兼容。

解决方案缺点:

  • 需要运行两个查询
  • 要求搜索客户端中的代码将一个查询的结果合并到另一个查询中。

使用Solr 4.8+,您可以在每个主文档(文本)下面嵌套子文档(注释)......

Collection<JComboBox<String>> myJComboBox = new ArrayList<JComboBox<String>>();

...使用块连接来查询注释。

1)注释查询curl http://localhost:8983/solr/update/json?softCommit=true -H 'Content-type:application/json' -d ' [ { "id": "123", "text" : "Bill studied The Bill of Rights last summer.", "content_type": "source", "_childDocuments_": [ { "id": "123-1", "content_type": "source_annotation", "annotation": "William Brown", "start_offset": 0, "end_offset": 4 }, { "id": "123-2", "content_type": "source_annotation", "annotation": "legal term", "start_offset": 13, "end_offset": 31 }, { "id": "123-3", "content_type": "source_annotation", "annotation": "summer 2011", "start_offset": 32, "end_offset": 43 } ] } ]

http://localhost:8983/solr/query?fl=id,start_offset,end_offset&q={!child of=content_type:source}annotation:"William Brown"

将这些结果存储在您的代码中,以便您可以在下一个查询返回后折叠注释偏移量。

2)来源查询+突出显示"response":{"numFound":1,"start":0, "docs":[ { "id": "123-1", "content_type": "source_annotation", "annotation": "William Brown", "start_offset": 0, "end_offset": 4 } ] }

(在注释查询中发现的id:123将ORed转换为第二个查询)

http://localhost:8983/solr/query?hl=true&hl.fl=text&fq=content_type:source&q=text:"William Brown" OR id:123

注意:在此示例中,没有返回突出显示信息,因为搜索字词与任何"response":{"numFound":1,"start":0, "docs":[ { "id": "123", "content_type": "source", "text": "Bill studied The Bill of Rights last summer." } ], "highlighting":{} } 文档都不匹配。但是,我们在第一个查询中有明确的注释和偏移量!

然后,您的客户端代码需要从第一个查询中获取content_type:source结果,并在第二个查询的content_type:source_annotation结果中手动插入突出显示标记。

Yonik's blog here上的更多阻止加入信息。