我正在使用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”:在设置它时对象中的“某个日期”。
答案 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
}