尝试将日期映射到ElasticSearch中的索引

时间:2017-12-06 20:05:48

标签: elasticsearch-5

我正在使用ElasticSearch并尝试使用其中包含动态类型属性的类创建索引。此属性可能包含字符串或日期。索引时,我一直在使用以下代码:

dynamic instance = MyObject.GetDynamicJson();
var indexResponse = client.Index((object) instance, i=>i
                .Index("myIndex")
                .Type("MyObject")
            );

这是GetDynamicJson()的代码。 MyObject只有Name和Value作为属性。 (道歉,我过去曾遇到过json choking而没有引用所有引号的问题,我已经用\ _字符进行了转义):

String json = "{ \"Name\":\" + Name + "\",\"DateValue\":\"";
try {
     var date = DateTime.parse(Value);
     json += DateTime.ToString("yyyy/MM/dd HH:mm:ss Z") + "\", \"Value\":\"\"}";
} catch {   //If the DateTime parse fails, DateValue is empty and I'll have text in Value
     json += "\",\"Value\":\"" + Value + "\"}";
}
return json;

   由于某些原因,它似乎不喜欢DateValue中的字符串,我绝对不知道为什么它完全在错误中遗漏了该属性:

无论出于何种原因,ElasticSearch完全转储DateValue属性,似乎根本看不到DateValue属性。

我收到了错误:
{ “名称”: “CreatedDate”, “值”: “2017-11-07T13:37:11.4340238-06:00”} [indices:data / write / bulk [s] [p]]“}],”type“:”class_cast_exception“,”reason“:”org.elasticsearch.index.mapper.TextFieldMapper无法强制转换为org.elasticsearch.index .mapper.DateFieldMapper “},” 状态“:500

稍后注意:我已更改索引创建者方法以更新映射。我在Object中添加了第三个字段,所以它现在具有属性:Name,Value,DateValue:

public static void CreateRecordsIndex(ElasticClient client)
    {
        client.CreateIndex("myIndex", i => i
            .Settings(s => s
                .NumberOfShards(2)
                .NumberOfReplicas(0)
            )
            .Mappings(x => x
                .Map<MyObject>(m => m.AutoMap())));
    }

现在,它每次都成功映射并创建一个属性,但它似乎仍然删除了我在json中发送它的属性。它只是将它们全部设置为默认日期时间:“dateValue”:“0001-01-01T00:00:00”。这很奇怪,因为在制作我发送给Elastic的动态实例时,我只使用MyObject.GetDynamicJson()方法来构建它。我不再得到映射错误,但Elastic仍然似乎忘记了“dateValue”:在设置它时对象中的“某个日期”。

1 个答案:

答案 0 :(得分:0)

好的,我摆脱了动态对象类型(最终我实际上并没有从json方法获取数据,我有一个拼写错误,Elastic正在直接获取原始对象 - 它很奇怪它是还在处理它)。所以我让Elastic使用它的映射来解析。为了做到这一点,我首先更新了MyObject以包含多个属性,每个类型对应一个传入属性(在这种情况下我只处理文本和日期)。对于MyObject的DateValue属性,我有:

public DateTime DateValue { 
        get
        {
            try
            {
                return DateTime.Parse(Value);
            } catch
            {
                return new DateTime();
            }
        }
        set
        {
            try {
                DateValue = value;
            } catch
            {
                DateValue = new DateTime();
            }
        }
    }

现在,如果Value是一个日期,我的DateValue字段将被设置。否则它将具有默认日期(非常早的日期&#34; 0001-01-01T00:00:00&#34;)。这样,我以后可以针对该动态字段搜索文本,或者如果设置了日期,我可以针对它进行日期和日期范围查询(从技术上讲,它们最终会出现在两个不同的字段中,但来自相同的受阻数据)

关键是拥有索引映射设置,正如您在此方法中可以从问题中看到的那样:

public static void CreateRecordsIndex(ElasticClient client)
{
    client.CreateIndex("myIndex", i => i
        .Settings(s => s
            .NumberOfShards(2)
            .NumberOfReplicas(0)
        )
        .Mappings(x => x
            .Map<MyObject>(m => m.AutoMap())));
}

为了使用更新的MyObject重新创建索引,我这样做了:

if (client.IndexExists("myIndex").Exists)
        {
            client.DeleteIndex("myIndex");
            CreateRecordsIndex(client);  //Goes to the method above
        }