elasticsearch - 如何正确地将别名指向索引?

标签 elasticsearch nest

我正在创建一个带有时间戳的 elasticsearch 索引,并将别名指向它。

喜欢:indexname = index-201512302002515529,alias = index

因此,如果我需要重建索引,我会创建一个新索引(使用另一个时间戳),在索引完成时将别名指向它并删除旧索引。

该过程有效,但在使用别名搜索索引时,我总是得到零命中。

我在连接设置的 SetDefaultIndex() 上使用别名。

创建索引:

    var timeStamp = DateTime.Now.ToString("yyyyMMddHHmmssffff");
    var indexName = string.Concat(containerName, "-", timeStamp);

    CreateIndex(indexName);
    Console.WriteLine($"Creating index {indexName}...");

    //do the indexing
    Console.WriteLine("Indexing from Database...");
    IndexAllFromDb();

    //delete aliases
    if (cli.AliasExists(containerName).Exists)
    {
        Console.WriteLine("Deleting Aliases...");
        foreach (var index in cli.GetIndicesPointingToAlias(containerName))
        {
            cli.Alias(a => a
                .Remove(remove => remove
                    .Index(index)
                    .Alias(containerName)
                )
            );
        }
    }

    Console.WriteLine("Creating Aliases...");
    //create the alias
    cli.Alias(a => a
        .Add(add => add
            .Index(indexName)
            .Alias(containerName)
        )
    );

CreateIndex(indexName) 创建所有映射和分析设置。 IndexAllFromDB() 读取 SQL 数据库并进行索引。

我正在使用此代码进行连接:

    var settings = new ConnectionSettings(new Uri(connectionString));
    settings.SetDefaultIndex(SiteSettings.Settings.SearchContainerName);

    var cli = new ElasticClient(settings);

如果我直接使用别名创建索引,它就可以工作,所以我可能对别名做错了....

谢谢。

最佳答案

使用别名作为 ConnectionSettings 上的默认索引是可以的;除了您在评论中提到的错误之外,我可以通过您当前的方法看到两件潜在的事情:

  • 您一次删除一个别名,然后将别名添加到新索引中。这些操作可以在一个操作中以原子方式执行
  • 索引中分片的默认刷新间隔为 1 秒,因此您可能会在此刷新之前进行搜索。您可能需要考虑在所有索引编制完成后进行刷新,以确保新编制索引的文档出现在搜索结果中。

我整理了这个示例,可以帮助您开始

void Main()
{
    var containerName = "index";

    var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
        .SetDefaultIndex(containerName)
        .ExposeRawResponse(true)
        .SetConnectionStatusHandler(response =>
        {
            // log out the requests
            if (response.Request != null)
            {
                Console.WriteLine("{0} {1} \n{2}\n", response.RequestMethod.ToUpperInvariant(), response.RequestUrl,
                    Encoding.UTF8.GetString(response.Request));
            }
            else
            {
                Console.WriteLine("{0} {1}\n", response.RequestMethod.ToUpperInvariant(), response.RequestUrl);
            }

            if (response.ResponseRaw != null)
            {
                Console.WriteLine("Status: {0}\n{1}\n\n{2}\n", response.HttpStatusCode, Encoding.UTF8.GetString(response.ResponseRaw), new String('-', 30));
            }
            else
            {
                Console.WriteLine("Status: {0}\n\n{1}\n", response.HttpStatusCode, new String('-', 30));
            }
        });

    var client = new ElasticClient(settings);

    var timeStamp = DateTime.Now.ToString("yyyyMMddHHmmssffff");
    var indexName = string.Concat(containerName, "-", timeStamp);

    var indexResponse = client.CreateIndex(indexName, c => c
        .AddMapping<Item>(m => m
            .MapFromAttributes()
        )
    );

    //do the indexing
    Console.WriteLine("Indexing from Database...");
    IndexAllFromDb(client, indexName);

    // add alias to the new index
    var aliasDescriptor = new AliasDescriptor()
        .Add(add => add.Alias(containerName).Index(indexName));

    // get any existing indices that have the alias
    Console.WriteLine($"Get existing indices with alias '{containerName}'");
    var aliasesResponses = client.GetAliases(a => a.Alias(containerName));

    foreach (var index in aliasesResponses.Indices)
    {
        if (index.Value.Any(a => a.Name == containerName))
        {
            Console.WriteLine($"Removing alias from index '{index.Key}'");
            aliasDescriptor.Remove(remove => remove.Alias(containerName).Index(index.Key));
        }
    }

    // atomic add and delete
    var aliasResponse = client.Alias(aliasDescriptor);

    var countResponse = client.Search<Item>(s => s.SearchType(SearchType.Count));

    Console.WriteLine($"{countResponse.Total} items");
}

private static void IndexAllFromDb(IElasticClient client, string indexName)
{
    var items = Enumerable.Range(1, 1000).Select(i => Item.Create(i));

    // refresh shards manually as opposed to relying on the refresh interval
    // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html#index-refresh
    var indexManyResponse = client.Bulk(b => b.IndexMany(items, (bi, i) => bi.Index(indexName).Document(i)).Refresh());
}

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }

    public static Item Create(int id)
    {
        return new Item { Id = id, Name = "Item " + id };
    }
}

第二次运行(以确保存在应用别名的现有索引)产生以下结果

POST http://localhost:9200/index-201601011621518238 
{
  "settings": {
    "index": {}
  },
  "mappings": {
    "item": {
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        }
      }
    }
  }
}

Status: 200
{"acknowledged":true}

------------------------------

Indexing from Database...
POST http://localhost:9200/_bulk?refresh=true 
{ "index" :  {"_index":"index-201601011621518238","_type":"item","_id":"1"} }
{"id":1,"name":"Item 1"}
// ... cut out for brevity
{ "index" :  {"_index":"index-201601011621518238","_type":"item","_id":"1000"} }
{"id":1000,"name":"Item 1000"}


Status: 200
{"took":124,"errors":false,"items":[{"index":{"_index":"index-201601011621518238","_type":"item","_id":"1","_version":1,"status":201}},
// ... cut out for brevity
{"index":{"_index":"index-201601011621518238","_type":"item","_id":"1000","_version":1,"status":201}}]}
------------------------------

Get existing indices with alias 'index'
GET http://localhost:9200/_aliases/index

Status: 200
{"index-201601011616271553":{"aliases":{"index":{}}},"index-201601011621518238":{"aliases":{}}}

------------------------------

Removing alias from index 'index-201601011616271553'
POST http://localhost:9200/_aliases 
{
  "actions": [
    {
      "add": {
        "index": "index-201601011621518238",
        "alias": "index"
      }
    },
    {
      "remove": {
        "index": "index-201601011616271553",
        "alias": "index"
      }
    }
  ]
}

Status: 200
{"acknowledged":true}

------------------------------

POST http://localhost:9200/index/item/_search?search_type=count 
{}

Status: 200
{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1000,"max_score":0.0,"hits":[]}}

------------------------------

1000 items

关于elasticsearch - 如何正确地将别名指向索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34538204/

相关文章:

php - 多个指标上的相同聚合Elasticsearch

logging - 如何使用 Logstash 处理多个异构输入?

elasticsearch - 有没有办法反序列化 Elasticsearch Nest 搜索查询?

angular - 用Elasticsearch在Angular中搜索

elasticsearch - 使用JEST在ElasticSearch中进行部分更新

symfony - 自动完成+ elasticsearch + symfony2

vb.net - ElasticSearch分析的字段

elasticsearch - 如何最好地解决NEST中的索引属性子字段?

c# - 如何在 ElasticSearch 中使用 NEST 指定 index.mapping.ignore_malformed 设置

elasticsearch - 如何使用Elasticsearch搜索所有同义词?