Elasticsearch.Nest 教程系列 9-7 转换:Indices Paths | 索引路径

  • 本系列博文是“伪”官方文档翻译(更加本土化),并非完全将官方文档进行翻译,而是在查阅、测试原始文档并转换为自己真知灼见后的“准”翻译。有不同见解 / 说明不周的地方,还请海涵、不吝拍砖 :)

  • 官方文档见此:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/introduction.html

  • 本系列对应的版本环境:ElasticSearch@7.3.1,NEST@7.3.1,IDE 和开发平台默认为 VS2019,.NET CORE 2.1


Elasticsearch 中的某些API在请求的 URI 中回需要使用索引名称,索引名称的集合或特殊的 _all 标记(表示所有索引),以指定在哪个(哪些)索引上进行请求。

在 Nest 中,这些索引的名称通过 Indices 类型来进行指定。

显式指定

以下几种类型会隐式转换:

  • string。

  • 逗号分隔的 string。

  • string 数组。

  • 已经在 ConnectionSettings 上设置相关类型的索引名称的 CLR 类。

  • IndexName 类

  • IndexName 数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Nest.Indices singleIndexFromString = "name";
Nest.Indices multipleIndicesFromString = "name1, name2";
Nest.Indices multipleIndicesFromStringArray = new [] { "name1", "name2" };
Nest.Indices allFromString = "_all";

Nest.Indices allWithOthersFromString = "_all, name2";

Nest.Indices singleIndexFromType = typeof(Project);

Nest.Indices singleIndexFromIndexName = IndexName.From<Project>();

singleIndexFromString.Match(
all => all.Should().BeNull(),
many => many.Indices.Should().HaveCount(1).And.Contain("name")
);

multipleIndicesFromString.Match(
all => all.Should().BeNull(),
many => many.Indices.Should().HaveCount(2).And.Contain("name2")
);

allFromString.Match(
all => all.Should().NotBeNull(),
many => many.Indices.Should().BeNull()
);

allWithOthersFromString.Match(
all => all.Should().NotBeNull(),
many => many.Indices.Should().BeNull()
);

multipleIndicesFromStringArray.Match(
all => all.Should().BeNull(),
many => many.Indices.Should().HaveCount(2).And.Contain("name2")
);

singleIndexFromType.Match(
all => all.Should().BeNull(),
many => many.Indices.Should().HaveCount(1).And.Contain(typeof(Project))
);

singleIndexFromIndexName.Match(
all => all.Should().BeNull(),
many => many.Indices.Should().HaveCount(1).And.Contain(typeof(Project))
);
  • _all 会覆盖所有指定的索引名称。

  • Project 类已经通过在 ConnectionSettings…DefaultMappingFor 指定索引名称。

使用 Nest.Indices 方法

为了简化创建 IndexName 或者 Indices 实例,Nest.Indices 包含了好几个静态方法供使用。

单索引

单索引可以通过使用 CLR 类、字符串或者 .Index() 方法来进行指定。

1
2
3
4
5
6
7
8
9
10
var client = TestClient.Default;

var singleString = Nest.Indices.Index("name1"); //通过字符串"name1"进行指定
var singleTyped = Nest.Indices.Index<Project>(); //通过 Project 类进行指定。

ISearchRequest singleStringRequest = new SearchDescriptor<Project>().Index(singleString);
ISearchRequest singleTypedRequest = new SearchDescriptor<Project>().Index(singleTyped);

((IUrlParameter)singleStringRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("name1");
((IUrlParameter)singleTypedRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("project");

多索引

跟单索引类似,可以通过使用多个 CLR 类型或者 多个“字符串”来进行多索引的创建。

1
2
3
4
5
6
7
8
9
10
11
12
var manyStrings = Nest.Indices.Index("name1", "name2"); // 使用字符串
var manyTypes = Nest.Indices.Index<Project>().And<Developer>(); //使用 CLR 类
var client = TestClient.Default;

ISearchRequest manyStringRequest = new SearchDescriptor<Project>().Index(manyStrings);
ISearchRequest manyTypedRequest = new SearchDescriptor<Project>().Index(manyTypes);

((IUrlParameter)manyStringRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("name1,name2");
((IUrlParameter)manyTypedRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("project,devs"); //这里的索引名称来自于 TestClient 中配置的 ConnectionSetting

manyStringRequest = new SearchDescriptor<Project>().Index(new[] { "name1", "name2" });
((IUrlParameter)manyStringRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("name1,name2");

所有索引

通过 _all 标识,你可以在 ES 的所有索引中进行查询。

Nest 提供了 Indices.All 以及 Indices.AllIndices 来对外暴露 _all 标记。

为什么要提供这 2 个属性而不是一个:Indices.All 或者 Indices.AllIndices?

  • 因为你可能同时使用了 Nest.Indices 和 Nest.Type,并且还使用了 C# 6 的一些特性,这种情况下,Indices.All 和 Types.All 的All 属性就变得摸棱两可了,为了消除这种歧义,应使用 Indices.AllIndices 来代表 _all 标记。

1
2
3
4
5
6
7
8
var indicesAll = Nest.Indices.All;
var allIndices = Nest.Indices.AllIndices;

ISearchRequest indicesAllRequest = new SearchDescriptor<Project>().Index(indicesAll);
ISearchRequest allIndicesRequest = new SearchDescriptor<Project>().Index(allIndices);

((IUrlParameter)indicesAllRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("_all");
((IUrlParameter)allIndicesRequest.Index).GetString(this.Client.ConnectionSettings).Should().Be("_all");