如何更改Elasticsearch通过NEST索引的字典中条目的映射字段名称?

时间:2016-01-08 22:12:05

标签: elasticsearch 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生成一个名为&#34; DynamicValues.MyKey&#34;的Lucene字段。这个价值。由于一些遗留问题(现场的现有查询),我需要Lucene字段为&#34; MyKey&#34; - 并且不以&#34; DynamicValues为前缀。&#34;

有人知道如何实现这一目标吗?我已经看过各种映射方法,但没有运气。我无法弄清楚如何指定Lucene字段名称 - 只是应该分析等等.I

1 个答案:

答案 0 :(得分:1)

有一种方法可以达到你想要的效果。将IdGeometryHotspot键值添加到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
               }
            }
         }
      ]
   }
}

希望这有帮助。