首页 / 教程列表 / Elasticsearch.NET/NEST中文文档(教程) / 使用Elasticsearch.Net发送数据

使用Elasticsearch.Net发送数据

967 发布于: 2021-03-26 读完约需 4 分钟

概要

低阶客户端Elasticsearch.Net允许你直接向远程Elasticsearch服务发送字符串或字节数组。除此之外,如果传递字符串或对象的集合,它们将使用Elasticsearch的特殊的bulk/multi等进行序列化。

隐式转换

虽然低阶客户端Elasticsearch.Net上的PostData参数使用了PostData对象,但对于最常见的两个用例,你可以依赖隐式转换来抽象PostData的概念。

下面用示例来说明:

PostData fromString = @string;
PostData fromByteArray = bytes;

fromByteArray.WrittenBytes.Should().BeSameAs(bytes); // 如果WrittenBytes来自byte[],则它将始终被设置。

Type属性代表了构造发送数据的原始类型:

fromString.Type.Should().Be(PostType.LiteralString);
fromByteArray.Type.Should().Be(PostType.ByteArray);

并且将PostData实例传递给接受PostData作为参数的方法不会再次包装它:

fromString = MethodThatAcceptsPostData(fromString);
fromByteArray = MethodThatAcceptsPostData(fromByteArray);

fromString.Type.Should().Be(PostType.LiteralString);
fromByteArray.Type.Should().Be(PostType.ByteArray);

PostData的其他类型

还可以将下列对象直接传递给Elasticsearch.Net低阶客户端:

  • 序列化的对象
  • 多行json对象的集合
  • 多行json的字符串集合

以下示例演示如何使用静态帮助方法来处理这些问题:

PostData fromObject = PostData.Serializable(@object);
PostData fromListOfString = PostData.MultiJson(collectionOfStrings);
PostData fromListOfObject = PostData.MultiJson(collectionOfObjects);

Type属性代表了构造发送数据的原始类型:

fromListOfString.Type.Should().Be(PostType.EnumerableOfString);
fromListOfObject.Type.Should().Be(PostType.EnumerableOfObject);
fromObject.Type.Should().Be(PostType.Serializable);

并且将PostData实例传递给接受PostData作为参数的方法不会再次包装它:

fromListOfString = MethodThatAcceptsPostData(fromListOfString);
fromListOfObject = MethodThatAcceptsPostData(fromListOfObject);
fromObject = MethodThatAcceptsPostData(fromObject);

fromListOfString.Type.Should().Be(PostType.EnumerableOfString);
fromListOfObject.Type.Should().Be(PostType.EnumerableOfObject);
fromObject.Type.Should().Be(PostType.Serializable);

每种隐式转换类型的行为略有不同。

对于字符串string来说,请求中发送的是UTF-8字节,并指定WrittenBytes属性:

await Post(() => @string, writes: Utf8Bytes(@string), writtenBytesIsSet: true, settings: settings);

类似地,对于字节数组byte[]来说,请求中字节被逐字发送,并指定WrittenBytes属性:

await Post(() => bytes, writes: bytes, writtenBytesIsSet: true, settings: settings);

在支持ReadOnlyMemory<byte>的平台上,你可以使用PostData.ReadOnlyMemory直接发送数据:

await Post(() => PostData.ReadOnlyMemory(bytes.AsMemory()), writes: bytes, writtenBytesIsSet: false, settings: settings);

当发送一个字符串集合时,Elasticsearch.Net客户端假定它是一个有效的序列化json集合,因此将每个集合与换行符连接起来,确保末尾有一个换行符。

stringbyte[]一样,如果在ConnectionConfiguration中设置了DisableDirectStreamingWrittenBytes属性被指定为字符串集合的UTF-8字节:

await Post(() => PostData.MultiJson(collectionOfStrings), writes: utf8BytesOfListOfStrings, writtenBytesIsSet: false, settings: settings);

当发送的数据是一个对象集合时,Elasticsearch.Net客户端假定它是一个对象集合,需要单独序列化为json并使用换行符进行连接。与字符串集合一样,客户端会确保末尾有换行符:

await Post(() => PostData.MultiJson(collectionOfObjects), writes: utf8BytesOfCollectionOfObjects, writtenBytesIsSet: false, settings: settings);

在所有其他情况下,发送的数据按原样进行序列化,而WrittenBytes不会被指定:

await Post(() => PostData.Serializable(@object), writes: utf8ObjectBytes, writtenBytesIsSet: false, settings: settings);

如果你想要更多地控制如何将数据写入数据流,可以考虑使用PostData.StreamHandler,它允许你注入自己的写入规则:

var streamHandler = PostData.StreamHandler(bytes,
    (b, s) => s.Write(b.AsSpan()),
    async (b, s, ctx) => await s.WriteAsync(b.AsMemory(), ctx)
);
await Post(() => streamHandler, writes: bytes, writtenBytesIsSet: false, settings: settings);

强制设置WrittenBytes

如果你想要维护发出请求的副本,可以在ConnectionConfiguration上设置DisableDirectStreaming。如此,序列化的字节首先被写入私有内存流,以便客户端可以获得序列化的字节:

settings = new ConnectionConfiguration().DisableDirectStreaming();

await Post(() => PostData.MultiJson(collectionOfObjects), writes: utf8BytesOfCollectionOfObjects, writtenBytesIsSet: true, settings: settings);

await Post(() => PostData.MultiJson(collectionOfStrings), writes: utf8BytesOfListOfStrings, writtenBytesIsSet: true, settings: settings);

await Post(() => PostData.ReadOnlyMemory(bytes.AsMemory()), writes: bytes, writtenBytesIsSet: true, settings: settings);

await Post(() => streamHandler, writes: bytes, writtenBytesIsSet: true, settings: settings);

当启用DisableDirectStreaming序列化一个简单对象时,也可以使用客户端获取到发送给远程Elasticsearch服务的序列化的请求数据:

await Post(() => PostData.Serializable(@object), writes: utf8ObjectBytes, writtenBytesIsSet: true, settings: settings);

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

发表评论

登录用户才能发表评论, 请 登 录 或者 注册