如何更改字典中条目的映射字段名称以通过 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 字段名称 - 只是它是否应该被分析等。我

有一种方法可以实现你想要的。将 IdGeometryHotspot 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
               }
            }
         }
      ]
   }
}

希望对您有所帮助。