2017-08-30 81 views
2

我有一个索引文档的服务。 该服务收到两个以下请求 - 第一个是插入文档,第二个是删除它。 当它们之间存在一段时间时,它可以正常工作,但是当它们一个接一个地发送时,文档不会被删除。 我从Nest获得的回应看起来很成功。如果在插入请求后立即发送删除请求,则文档不会被删除

我的功能很长,所以我只会写入插入和删除里面。如果需要更多信息,我将添加它(例如,如果插入也会将其从所有其他可用索引中删除,并在需要时插入一些映射)。

插入代码:

IBulkResponse res = await _client.IndexManyAsync(entities, index, type); 

删除代码:

var termFilter = new List<Func<QueryContainerDescriptor<JObject>, QueryContainer>> 
     { 
      c => c.Terms(t => t.Field(ID_FIELD).Terms(ids)) 
     }; 

     await _client.DeleteByQueryAsync<JObject>(indices, types, d => d.Query(q => q.Bool(b => b.Must(termFilter)))); 

例如,这种集成测试不起作用:

var indices = new { "some_index_1", "some_index_2" }; 
var entity = new Entity { Action = ReplicationAction.INSERT, ... }; 
await elasticDal.Insert(new List { entity }, "some_index_1", "666", indices); 
entity.Action = ReplicationAction.DELETE; 
await elasticDal.Insert(new List { entity }, "some_index_1", "666", indices); 

版本:2.3.5 ElasticSearch,。 Net 4.6,Nest 2.4.6

回答

0

当您在以下步骤中插入任何文档时:

  1. 将文档添加到内存缓冲区并附加到translog。
  2. 刷新 内存缓冲区中的文档被写入到一个新的段,而没有 fsync。

    a。该部分已打开,使其可以进行搜索。

    b。内存中的缓冲区被清除。

  3. 该部分已打开以使其可见。

  4. 每隔一段时间 - 例如当过度日志变得太大 - 索引是 被刷新;创建新的超时日志,并且执行完整的提交:

    a。内存缓冲区中的任何文档都写入新的段。

    b。缓冲区被清除。

    c。提交点写入磁盘。

    d。文件系统缓存刷新fsync。

    e。旧的转换日志被删除。

Elasticsearch不会删除该文件,它标志着文档删除文件,而合并,如果它在内存中删除文档的索引段ES叶。

所以我的猜测是你在删除后缺少刷新API。 如果您的DELETE API不是那么频繁,那么通过调用REFRESH API调用DELETE API后,您可以刷新ES。

如果您想了解更多关于索引是如何happing您可以参考此链接(https://www.elastic.co/guide/en/elasticsearch/guide/current/translog.html

+0

的删除是在这种情况下,相当频繁的画面背后。还有其他一些情况,我需要一次删除多个文档。我还应该使用刷新api吗?如果没有,我还能做什么? – Mei

+0

我刚刚尝试使用刷新api(等待_client.RefreshAsync(新RefreshRequest(indices))),但它帮助 – Mei

+0

ES每秒刷新一次。因此,如果你说两秒钟就可以睡一觉,如果你的频率小于每秒一个文件,你可以刷新。 但我的建议是睡一秒钟。 –