0

我刚刚将我的 Nest nuget 从 0.9.20.6 更新到最新版本 0.11.1.0,现在我得到了一个创建索引的空对象引用。我的代码没有改变,但也许它从来都不是正确的。我还将 Json.Net 更新为 v 5.0.6.2,调用堆栈表明 JsonSerializer 是它失败的地方。

调用堆栈因此是:

at Nest.Resolvers.Converters.IndexSettingsConverter.<>c__DisplayClass2.b__0(RootObjectMapping m) in c:\Work\NEST\src\Nest\Resolvers\Converters\IndexSettingsConverter.cs:line 113
at System.Linq.Enumerable.ToDictionaryTSource,TKey,TElement
at System.Linq.Enumerable.ToDictionaryTSource,TKey
at Nest.Resolvers.Converters.IndexSettingsConverter.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer) in c:\Work\NEST\src\Nest\Resolvers\Converters\IndexSettingsConverter.cs:line 112
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConvertable(JsonWriter writer, JsonConverter converter, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Type type, Formatting formatting, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Formatting formatting, JsonSerializerSettings settings)
at Nest.ElasticClient.Serialize(Object object) in c:\Work\NEST\src\Nest\ElasticClient-Statics.cs:line 53
at Nest.ElasticClient.CreateIndex(String index, IndexSettings settings) in c:\Work\NEST\src\Nest\ElasticClient-CreateIndex.cs:line 18
...

这是失败的,因为字段映射具有 null TypeNameMarker 属性(请参阅上面跟踪中第一行的 Nest 源)。

我手动创建了字段映射(来自应用程序中的一些 XML 定义),因此:

new StringMapping() { Name = fieldname, Index = idx, Store = field.Store };

有谁知道为什么这会改变?

更新

这是我用来创建地图的完整代码。您可以看到我已经注释掉了 TypeNameMarker,因为这是 0.11 的新属性。

    IElasticType createFieldMap(Field field, bool notAnalyzed = false, string fieldname = null)
    {
        IElasticType att = null;

        var idx = notAnalyzed ? FieldIndexOption.not_analyzed : (FieldIndexOption?)Enum.Parse(typeof(FieldIndexOption), field.Index);
        var nsidx = notAnalyzed ? NonStringIndexOption.not_analyzed : (NonStringIndexOption?)Enum.Parse(typeof(NonStringIndexOption), field.Index);
        var ft = (FieldType)Enum.Parse(typeof(FieldType), field.Type);

        fieldname = fieldname ?? field.Name;

        switch (ft)
        {
            case FieldType.string_type:
                att = new StringMapping()
                {
                    Name = fieldname,
                    Index = idx,
                    Store = field.Store,
                    //TypeNameMarker = "string"
                };
                if (field.CodeField)
                {
                    (att as StringMapping).SearchAnalyzer = "keyword";
                    (att as StringMapping).IndexAnalyzer = "keyword";
                }
                else
                {
                    (att as StringMapping).SearchAnalyzer = "simple";
                    (att as StringMapping).IndexAnalyzer = "simple";
                }
                break;
            case FieldType.binary:
                att = new BinaryMapping()
                {
                    Name = fieldname,
                    //TypeNameMarker = "binary"
                };
                break;
            case FieldType.boolean_type:
                att = new BooleanMapping()
                {
                    Name = fieldname,
                    Index = nsidx,
                    Store = field.Store,
                    //TypeNameMarker = "boolean"
                };
                break;
            case FieldType.date_type:
                att = new DateMapping()
                {
                    Name = fieldname,
                    Index = nsidx,
                    Store = field.Store,
                    //TypeNameMarker = "date"
                };
                break;
            case FieldType.double_type:
            case FieldType.float_type:
            case FieldType.integer_type:
            case FieldType.long_type:
                att = new NumberMapping()
                {
                    Name = fieldname,
                    Index = nsidx,
                    Store = field.Store,
                    //TypeNameMarker = "number"
                };
                break;
        }
        return att;
    }

每个字段都添加到根映射中。

var props = new Dictionary<string, IElasticType>();

foreach (var field in doc.IndexMap.Fields)
{
    if (!field.Sortable)
    {
        props.Add(field.Name, createFieldMap(field));
    }
    else
    {
        var mfm = new MultiFieldMapping();
        mfm.Name = field.Name;

        mfm.Fields.Add(field.Name, (IElasticCoreType)createFieldMap(field));
        mfm.Fields.Add("sort", (IElasticCoreType)createFieldMap(field, true, "sort"));

        props.Add(field.Name, mfm);
    }
  }
  rootMap.Properties = props;

有一个大型 xml 文件,其中包含要包含在索引中的字段列表。实际记录是从 SQL 返回的,并且这个相同的 XML 文件具有要执行的查询和一些更改跟踪信息(使用 rowversions)。

4

1 回答 1

1

我设法在失败的单元测试中发现了错误

发生的情况是,如果您使用该.MapFluent()方法,它会确保在幕后为您设置 TypeNameMarker。如果您手动新建映射对象,则代码IndexSettingsConverter.cs:line 113不会优雅地退回.Name

现在已修复此问题,如果两者都丢失,我们会抛出更好的.Name异常.TypeNameMarker

于 2013-07-26T07:52:26.373 回答