如何更改字典中条目的映射字段名称以通过 NEST 由 Elasticsearch 索引?
How can I change the mapped field name of an entry in a dictionary to be indexed by Elasticsearch via NEST?
我需要索引一些动态数据(这些字段在编译时是未知的),我还需要索引一个 GeoPoint。
我想使用 NEST api 并在 Elasticsearch 中建立索引。我有以下代码来处理这个问题:
public class MyRow
{
public string Id { get; set; }
[ElasticProperty(Name = "GeometryHotspot", Type = FieldType.GeoPoint)]
public Coordinate GeometryHotspot { get; set; }
public Dictionary<string, object> DynamicValues { get; set; }
}
这行得通,但是当我像这样在数组中设置动态值时:
row.DynamicValues["MyKey"] = "Some value";
然后 Elasticsearch 为该值生成一个名为 "DynamicValues.MyKey" 的 Lucene 字段。由于一些遗留问题(该字段中的现有查询),我需要 Lucene 字段为 "MyKey" - 而不是前缀为 "DynamicValues."
有人知道如何实现吗?我看过各种映射方法,但没有运气。我不知道如何指定 Lucene 字段名称 - 只是它是否应该被分析等。我
有一种方法可以实现你想要的。将 Id
和 GeometryHotspot
key-values 添加到 DynamicValues
字典,然后索引 DynamicValues
而不是 MyRow
对象。您可以在这里使用 dynamic templates
的强大功能来实现您想要的映射。我写了一个小程序来说明这一点。
public class Coordinate
{
public float lat { get; set; }
public float lon { get; set; }
}
public class MyRow
{
public string Id { get; set; }
public Coordinate GeometryHotspot { get; set; }
public Dictionary<string, object> DynamicValues { get; set; }
}
class Program
{
static void Main(string[] args)
{
var row = new MyRow
{
Id = "randomid",
GeometryHotspot = new Coordinate
{
lat = 1.23f,
lon = 4.56f
},
DynamicValues = new Dictionary<string, object>
{
["numberField"] = 1,
["stringField"] = "TWO",
["dateField"] = DateTime.UtcNow,
["realNumberField"] = 25.6,
["booleanField"] = true
}
};
// Add the concrete fields of MyRow class to its DynamicValues property
row.DynamicValues["id"] = row.Id;
row.DynamicValues["geometryHotspot"] = row.GeometryHotspot;
var client = new ElasticClient(new ConnectionSettings(new Uri("http://localhost:9200")));
// Create a mapping called "myRow" in index "myindex". Make sure "myindex" exists already.
client.Map<object>(d => d
.Index("myindex")
.Type("myRow")
.DynamicTemplates(dtd => dtd
.Add(dd => dd
.Name("geopoint")
.Match("geometryHotspot")
.Mapping(fm => fm
.GeoPoint(f => f
.IndexLatLon())))));
client.Index(row.DynamicValues, d => d // Notice how we index row.DynamicValues and not row
.Index("myindex")
.Type("myRow"));
}
}
在此之后,只需搜索 "myindex" 索引和 "myRow" 类型中的所有文档,即可看到动态字段不再以 "DynamicFields." 字符串为前缀。
下面是 _search
API.
的输出
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "myindex",
"_type": "myRow",
"_id": "AVIqRf4rqbcnf7z9goAa",
"_score": 1,
"_source": {
"numberField": 1,
"stringField": "TWO",
"dateField": "2016-01-10T06:42:55.7535106Z",
"realNumberField": 25.6,
"booleanField": true,
"id": "randomid",
"geometryHotspot": {
"lat": 1.23,
"lon": 4.56
}
}
}
]
}
}
希望对您有所帮助。
我需要索引一些动态数据(这些字段在编译时是未知的),我还需要索引一个 GeoPoint。
我想使用 NEST api 并在 Elasticsearch 中建立索引。我有以下代码来处理这个问题:
public class MyRow
{
public string Id { get; set; }
[ElasticProperty(Name = "GeometryHotspot", Type = FieldType.GeoPoint)]
public Coordinate GeometryHotspot { get; set; }
public Dictionary<string, object> DynamicValues { get; set; }
}
这行得通,但是当我像这样在数组中设置动态值时:
row.DynamicValues["MyKey"] = "Some value";
然后 Elasticsearch 为该值生成一个名为 "DynamicValues.MyKey" 的 Lucene 字段。由于一些遗留问题(该字段中的现有查询),我需要 Lucene 字段为 "MyKey" - 而不是前缀为 "DynamicValues."
有人知道如何实现吗?我看过各种映射方法,但没有运气。我不知道如何指定 Lucene 字段名称 - 只是它是否应该被分析等。我
有一种方法可以实现你想要的。将 Id
和 GeometryHotspot
key-values 添加到 DynamicValues
字典,然后索引 DynamicValues
而不是 MyRow
对象。您可以在这里使用 dynamic templates
的强大功能来实现您想要的映射。我写了一个小程序来说明这一点。
public class Coordinate
{
public float lat { get; set; }
public float lon { get; set; }
}
public class MyRow
{
public string Id { get; set; }
public Coordinate GeometryHotspot { get; set; }
public Dictionary<string, object> DynamicValues { get; set; }
}
class Program
{
static void Main(string[] args)
{
var row = new MyRow
{
Id = "randomid",
GeometryHotspot = new Coordinate
{
lat = 1.23f,
lon = 4.56f
},
DynamicValues = new Dictionary<string, object>
{
["numberField"] = 1,
["stringField"] = "TWO",
["dateField"] = DateTime.UtcNow,
["realNumberField"] = 25.6,
["booleanField"] = true
}
};
// Add the concrete fields of MyRow class to its DynamicValues property
row.DynamicValues["id"] = row.Id;
row.DynamicValues["geometryHotspot"] = row.GeometryHotspot;
var client = new ElasticClient(new ConnectionSettings(new Uri("http://localhost:9200")));
// Create a mapping called "myRow" in index "myindex". Make sure "myindex" exists already.
client.Map<object>(d => d
.Index("myindex")
.Type("myRow")
.DynamicTemplates(dtd => dtd
.Add(dd => dd
.Name("geopoint")
.Match("geometryHotspot")
.Mapping(fm => fm
.GeoPoint(f => f
.IndexLatLon())))));
client.Index(row.DynamicValues, d => d // Notice how we index row.DynamicValues and not row
.Index("myindex")
.Type("myRow"));
}
}
在此之后,只需搜索 "myindex" 索引和 "myRow" 类型中的所有文档,即可看到动态字段不再以 "DynamicFields." 字符串为前缀。
下面是 _search
API.
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "myindex",
"_type": "myRow",
"_id": "AVIqRf4rqbcnf7z9goAa",
"_score": 1,
"_source": {
"numberField": 1,
"stringField": "TWO",
"dateField": "2016-01-10T06:42:55.7535106Z",
"realNumberField": 25.6,
"booleanField": true,
"id": "randomid",
"geometryHotspot": {
"lat": 1.23,
"lon": 4.56
}
}
}
]
}
}
希望对您有所帮助。