使用NEST 2.x创建具有多字段映射语法的索引

6 c# elasticsearch nest

我似乎无法在NEST 2.0中获得多字段映射的语法 - 如果这是正确的术语.我发现的每个映射示例似乎都是<= NEST的1.x版本.我是Elasticsearch和NEST的新手,我一直在阅读他们的文档,但NEST文档还没有完全更新2.x.

基本上,我不需要索引或存储整个类型.我只需要索引的一些字段,我需要索引和检索的一些字段,以及一些我不需要索引的字段,仅用于检索.

MyType
{
    // Index this & allow for retrieval.
    int Id { get; set; } 

    // Index this & allow for retrieval.
    // **Also**, in my searching & sorting, I need to sort on this **entire** field, not just individual tokens.
    string CompanyName { get; set; } 

    // Don't index this for searching, but do store for display.
    DateTime CreatedDate { get; set; }

    // Index this for searching BUT NOT for retrieval/displaying.
    string CompanyDescription { get; set; } 

    // Nest this.
    List<MyChildType> Locations { get; set; }
}

MyChildType
{
    // Index this & allow for retrieval.
    string LocationName { get; set; }

    // etc. other properties.
}
Run Code Online (Sandbox Code Playgroud)

已经能够索引整个对象和孩子一样,是使用以下为例:

client.Index(item, i => i.Index(indexName));
Run Code Online (Sandbox Code Playgroud)

但是,实际对象比这个要大很多,我真的不需要大部分.我发现了这个,看起来像我想要的那样,但是在旧版本中:多字段映射elasticsearch

我认为"映射"是我想要的,但就像我说的,我是Elasticsearch和NEST的新手,我正在努力学习术语.

要温柔!:)这是我第一次在SO上提问.谢谢!

Sel*_*glu 6

据我所知,你没有任何复杂的类型,你正在尝试映射.因此,您可以轻松使用NEST属性来映射对象.

看一下这个:

[Nest.ElasticsearchType]
public class MyType
{
    // Index this & allow for retrieval.
    [Nest.Number(Store=true)]
    int Id { get; set; }

    // Index this & allow for retrieval.
    // **Also**, in my searching & sorting, I need to sort on this **entire** field, not just individual tokens.
    [Nest.String(Store = true, Index=Nest.FieldIndexOption.Analyzed, TermVector=Nest.TermVectorOption.WithPositionsOffsets)]
    string CompanyName { get; set; }

    // Don't index this for searching, but do store for display.
    [Nest.Date(Store=true, Index=Nest.NonStringIndexOption.No)]
    DateTime CreatedDate { get; set; }

    // Index this for searching BUT NOT for retrieval/displaying.
    [Nest.String(Store=false, Index=Nest.FieldIndexOption.Analyzed)]
    string CompanyDescription { get; set; }

    [Nest.Nested(Store=true, IncludeInAll=true)]
    // Nest this.
    List<MyChildType> Locations { get; set; }
}

[Nest.ElasticsearchType]
public class MyChildType
{
    // Index this & allow for retrieval.
    [Nest.String(Store=true, Index = Nest.FieldIndexOption.Analyzed)]
    string LocationName { get; set; }

    // etc. other properties.
}
Run Code Online (Sandbox Code Playgroud)

在此声明之后,要在elasticsearch中创建此映射,您需要进行类似于以下的调用:

var mappingResponse = elasticClient.Map<MyType>(m => m.AutoMap());
Run Code Online (Sandbox Code Playgroud)

使用AutoMap()调用NEST将从POCO中读取您的属性并相应地创建映射请求.

另请参见此处的 "基于属性的映射"部分.

干杯!


Rus*_*Cam 6

除了ColinSelçuk的答案之外,您还可以通过流畅(和对象初始化语法)映射API完全控制映射.这是一个基于您的要求的示例

void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var connectionSettings = new ConnectionSettings(pool);

    var client = new ElasticClient(connectionSettings);

    client.Map<MyType>(m => m
        .Index("index-name")
        .AutoMap()
        .Properties(p => p
            .String(s => s
                .Name(n => n.CompanyName)
                .Fields(f => f
                    .String(ss => ss
                        .Name("raw")
                        .NotAnalyzed()
                    )
                )
            )
            .Date(d => d
                .Name(n => n.CreatedDate)
                .Index(NonStringIndexOption.No)         
            )
            .String(s => s
                .Name(n => n.CompanyDescription)
                .Store(false)
            )
            .Nested<MyChildType>(n => n
                .Name(nn => nn.Locations.First())
                .AutoMap()
                .Properties(pp => pp
                    /* properties of MyChildType */
                )
            )
        )
    );
}

public class MyType
{
    // Index this & allow for retrieval.
    public int Id { get; set; }

    // Index this & allow for retrieval.
    // **Also**, in my searching & sorting, I need to sort on this **entire** field, not just individual tokens.
    public string CompanyName { get; set; }

    // Don't index this for searching, but do store for display.
    public DateTime CreatedDate { get; set; }

    // Index this for searching BUT NOT for retrieval/displaying.
    public string CompanyDescription { get; set; }

    // Nest this.
    public List<MyChildType> Locations { get; set; }
}

public class MyChildType
{
    // Index this & allow for retrieval.
    public string LocationName { get; set; }

    // etc. other properties.
}
Run Code Online (Sandbox Code Playgroud)

这产生了映射

{
  "properties": {
    "id": {
      "type": "integer"
    },
    "companyName": {
      "type": "string",
      "fields": {
        "raw": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    },
    "createdDate": {
      "type": "date",
      "index": "no"
    },
    "companyDescription": {
      "type": "string",
      "store": false
    },
    "locations": {
      "type": "nested",
      "properties": {
        "locationName": {
          "type": "string"
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

调用.AutoMap()使NEST根据属性类型和应用于它们的任何属性推断映射.然后.Properties()覆盖任何推断的映射.例如

  • CompanyName被映射为a multi_field,companyName使用标准分析仪分析的字段,companyName.raw而不进行分析.您可以使用查询在查询中引用后者.Field(f => f.CompanyName.Suffix("raw"))
  • Locations被映射为一种nested类型(默认情况下自动化会将其推断为object类型映射).然后,您可以定义在调用内MyChildType使用的任何特定映射..Properties()Nested<MyChildType>()


cor*_*ore 0

我认为你至少有两种可能性来解决你的问题:

  1. 关于索引:创建类似元数据模型的东西,存储它只是为了检索。请参阅_source 字段以限制返回此字段。
  2. 搜索时:指定要查询的字段:如果您不想查询 CreatedDate,则不要将其包含在搜索中。

就我而言,我使用这两种方法来获得非常快的结果:-)