从查询中作为多值返回的单值字段
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
时,它被检索为 longs
的 ArrayList
。如果我尝试检索其他字段,我会得到同样的错误 - 我存储了一个字符串,但检索了它们的集合。这会崩溃,因为它试图创建 Record
的实例,其中 Id
属性 是单个 long
.
通过 Web 界面浏览索引显示 属性 确实是多值的 - 我看到的 JSON 包含所有属性的 array .同样,在模式浏览器中,我可以看到我的字段被定义为多值(对于属性和模式,而不是索引)。在索引的托管架构文件中,我可以看到我的字段定义为 strings
(对于字符串字段)或 tlongs
(对于数字字段)。
- 为什么 Solr(或 Solr.Net)将我的单值字段作为多值索引?
- 我可以在不手动编辑模式的情况下防止这种情况发生吗?也许使用字段属性?
- 我可以只检索一个多值 属性 的单个值吗,所以如果我无法修复架构,我可以简单地将数据检索到我的单值
Record
对象?
我找到了解决方案和解决方法。
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>
注意 strings
和 tlongs
数据类型。
为防止这种情况,您可以更改核心 conf
文件夹中的 solrconfig.xml
以使用单值数据类型(string
、tlong
等),或更改默认值新创建的核心的价值。
- 解决方法是将结果读取为
Dictionary<string,object>
,而不是让 Solr.NET 自动将结果反序列化到文档对象中。
这意味着为此类型初始化第二个 Solr 操作对象:
Startup.Init<Record>(indexUrl); // Typed
Startup.Init<Dictionary<string, object>>(indexUrl); // Untyped.
及以后,获取 ISolrOperations<Dictionary<string,object>>
的实例并从中手动读取我的 Key
和 Data
属性,将 object
有效负载转换为 ArrayList
并提取值。
我正在使用 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
时,它被检索为 longs
的 ArrayList
。如果我尝试检索其他字段,我会得到同样的错误 - 我存储了一个字符串,但检索了它们的集合。这会崩溃,因为它试图创建 Record
的实例,其中 Id
属性 是单个 long
.
通过 Web 界面浏览索引显示 属性 确实是多值的 - 我看到的 JSON 包含所有属性的 array .同样,在模式浏览器中,我可以看到我的字段被定义为多值(对于属性和模式,而不是索引)。在索引的托管架构文件中,我可以看到我的字段定义为 strings
(对于字符串字段)或 tlongs
(对于数字字段)。
- 为什么 Solr(或 Solr.Net)将我的单值字段作为多值索引?
- 我可以在不手动编辑模式的情况下防止这种情况发生吗?也许使用字段属性?
- 我可以只检索一个多值 属性 的单个值吗,所以如果我无法修复架构,我可以简单地将数据检索到我的单值
Record
对象?
我找到了解决方案和解决方法。
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>
注意 strings
和 tlongs
数据类型。
为防止这种情况,您可以更改核心 conf
文件夹中的 solrconfig.xml
以使用单值数据类型(string
、tlong
等),或更改默认值新创建的核心的价值。
- 解决方法是将结果读取为
Dictionary<string,object>
,而不是让 Solr.NET 自动将结果反序列化到文档对象中。
这意味着为此类型初始化第二个 Solr 操作对象:
Startup.Init<Record>(indexUrl); // Typed
Startup.Init<Dictionary<string, object>>(indexUrl); // Untyped.
及以后,获取 ISolrOperations<Dictionary<string,object>>
的实例并从中手动读取我的 Key
和 Data
属性,将 object
有效负载转换为 ArrayList
并提取值。