从查询中作为多值返回的单值字段

Single-value field returned as multi-value from query

我正在使用 Solr.NET 索引数据,稍后在本地 Solr 服务器(Solr.net v0.4,Solr v5.3.1)上查询它,并遇到奇怪的异常。

我的索引记录是一个简单的 class(此处简化):

public class Record
{
    [SolrUniqueKey]
    public long Id {get;set;}

    [SolrUniqueKey]
    public string Data {get;set;}
}

我通过调用 ISolrOperations.Add() 添加到索引中。我没有事先定义架构 - 它是由我输入的数据自动生成的。

在其他地方,我正在使用 ISolrReadOnlyOperations.Query() 查询此索引,仅询问 Id 字段。此查询显然 returns 结果,但因 ArgumentException:

而崩溃

"Could not convert value 'System.Collections.ArrayList' to property 'Id' of document type My.Namespace.Record"

意思是当我将 Id 属性 存储为 long 时,它被检索为 longsArrayList。如果我尝试检索其他字段,我会得到同样的错误 - 我存储了一个字符串,但检索了它们的集合。这会崩溃,因为它试图创建 Record 的实例,其中 Id 属性 是单个 long.

通过 Web 界面浏览索引显示 属性 确实是多值的 - 我看到的 JSON 包含所有属性的 array .同样,在模式浏览器中,我可以看到我的字段被定义为多值(对于属性和模式,而不是索引)。在索引的托管架构文件中,我可以看到我的字段定义为 strings(对于字符串字段)或 tlongs(对于数字字段)。

  1. 为什么 Solr(或 Solr.Net)将我的单值字段作为多值索引?
  2. 我可以在不手动编辑模式的情况下防止这种情况发生吗?也许使用字段属性?
  3. 我可以只检索一个多值 属性 的单个值吗,所以如果我无法修复架构,我可以简单地将数据检索到我的单值 Record对象?

我找到了解决方案和解决方法。

  1. Solr 5.3.1 中的新 indexes/cores,如果未明确提供 solrconfig.xml 文件,则复制在 <solr dir>\server\solr\configsets\data_driven_schema_configs\conf 中找到的默认文件。 该文件定义了一个 updateProcessRequestChain,它定义了在没有模式的情况下添加新文档时会发生什么。默认情况下,那里定义的类型是多值的:

    <processor class="solr.AddSchemaFieldsUpdateProcessorFactory"> <str name="defaultFieldType">strings</str> <lst name="typeMapping"> <str name="valueClass">java.lang.Long</str> <str name="valueClass">java.lang.Integer</str> <str name="fieldType">tlongs</str> </lst> </processor>

注意 stringstlongs 数据类型。 为防止这种情况,您可以更改核心 conf 文件夹中的 solrconfig.xml 以使用单值数据类型(stringtlong 等),或更改默认值新创建的核心的价值。

  1. 解决方法是将结果读取为 Dictionary<string,object>,而不是让 Solr.NET 自动将结果反序列化到文档对象中。

这意味着为此类型初始化第二个 Solr 操作对象:

   Startup.Init<Record>(indexUrl); // Typed
   Startup.Init<Dictionary<string, object>>(indexUrl); // Untyped.

及以后,获取 ISolrOperations<Dictionary<string,object>> 的实例并从中手动读取我的 KeyData 属性,将 object 有效负载转换为 ArrayList 并提取值。