solr如何使用“catch-all”字段_text_?

时间:2017-02-12 16:44:07

标签: solr

提取文件时,solr将其内容编入索引为_text_的全能字段。即使您通过fmap.content=my_content_field提供内容字段,也是如此。

但是,如果没有声明_text_字段,则字段fmap.content似乎会在更新时被覆盖。如果声明fmap.content,则字段_text_显然保持不变。

要重现此行为:

SOLR_CORE=test
SOLR_URL=http://192.168.45.153:8983/solr/${SOLR_CORE}
FILENAME=textfile.txt

cat > ${FILENAME} << EOF
Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
EOF

删除核心

中的所有文件
curl "${SOLR_URL}/update?commit=true&stream.body=<delete><query>*:*</query></delete>"

添加文档,提取并索引filename.txt的内容:

curl "${SOLR_URL}/update/extract?\
literal.id=${FILENAME}\
&fmap.content=my_content_field\
&literal.field_x=initial_text_of_field_x\
&literal.field_y=initial_text_of_field_y\
&commit=true"\
 -F "myfile=@${FILENAME}"

查询包含单词ipsum的文档:

curl "${SOLR_URL}/query?q=_text_:ipsum&fl=id"

更新字段field_x的内容:

curl "${SOLR_URL}/update?commit=true" -d '
[
  {
    "id" : '${FILENAME}',
    "field_x" : {"set" : "new_value"}
  }
]'

查询包含单词ipsum的文档:

curl "${SOLR_URL}/query?q=_text_:ipsum&fl=id"

更新前后的查询会给出按预期找到的文档的结果:

{
  "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
      "q":"_text_:ipsum",
      "fl":"id"}},
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"textfile.txt"}]
  }}

如果文档是在没有&fmap.content=my_content_field的情况下添加的:

curl "${SOLR_URL}/update/extract?\
literal.id=${FILENAME}\
&literal.field_x=initial_text_of_field_x\
&literal.field_y=initial_text_of_field_y\
&commit=true"\
 -F "myfile=@${FILENAME}"

更新后的查询(见上文)找不到文件:

curl "${SOLR_URL}/query?q=_text_:ipsum&fl=id"
{
  "responseHeader":{
    "status":0,
    "QTime":1,
    "params":{
      "q":"_text_:ipsum",
      "fl":"id"}},
  "response":{"numFound":0,"start":0,"docs":[]
  }}

1 个答案:

答案 0 :(得分:0)

这里的主要问题是更新命令必须重建文档,更新文档并将其提交回Lucene存储层。这是因为,在Lucene级别,内容是只写的。 Solr级别更新实际上会生成一个新的Lucene文档。

因此,要重建文档,它需要能够恢复字段。如果该字段未存储(或我认为是docValued),则无法这样做。

text 字段很可能不会被存储,因为它通常会累积许多其他字段的内容以方便默认搜索。因此,它没有参与重建,更新的文件错过了它。

我的猜测 my_content_field 是使用 stored = true 定义的,因此可以包含在重建的文档中,并与更新一起保存。