继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

ElasticSearch 遇见(5)

small_925_ant
关注TA
已关注
手记 69
粉丝 6395
获赞 157
希望给同样遇见es的你带来帮助,也希望彼此有更多的讨论
版本选择6.4.3
1- 别名的使用
   别名的使用
   索引修改重新索引数据 

别名的使用

我们可以给索引添加新的类型,或给类型添加新的字段,但是不能添加新的分析器或修改已有字段。修改在已存在的数据最简单的方法是重新索引:创建一个新配置好的索引,然后将所有的文档从旧的索引复制到新的上。
但是因为是新配置好的索引,所以我们的应用也会需要更新才能使用。这样就会极大的不方便,有时候不得不暂停使用我们的应用。因此,使用索引别名是必要的。可以做到在一个运行的集群上无缝的从一个索引切换到另一个。
  • 先在head插件上面删除我们之前创建的索引。
  • 首先创建索引别名
创建一个索引 comet_v1,然后将别名 comet指向它:
PUT comet_v1
{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 5,
    "index.store.type": "niofs",
    "index.query.default_field": "title",
    "index.unassigned.node_left.delayed_timeout": "5m"
  },

  "mappings": {
    "comet": {
      "dynamic": "strict",
      "properties": {
        "cometId": {
          "type": "long"
        },
        "title": {
          "type": "text",
          "analyzer": "ik_smart",
          "search_analyzer": "ik_smart"
        },
        "author": {
          "type": "text",
          "analyzer": "ik_smart",
          "search_analyzer": "ik_smart"
        },
        "editor": {
          "type": "keyword"
        },
        "category": {
          "type": "keyword"
        },
        "description": {
          "type": "text",
          "analyzer": "ik_smart",
          "search_analyzer": "ik_smart"
        },
        "content": {
          "type": "text",
          "analyzer": "ik_smart",
          "search_analyzer": "ik_smart"
        },
        "createTime": {
          "type": "date",
          "format": "strict_date_optional_time||epoch_millis"
        },
        "suggest": {
          "type": "completion"
        }
      }
    }
  }
}

设置别名为comet
PUT /comet_v1/_alias/comet
获取别名信息
GET /*/_alias/comet
  • 3 索引和别名设置好之后,我们需要导入测试数据了
数据导入完毕,我们可以进行简单的查询
首先介绍两个基本的查询
(1) match query:查询匹配会进行分词,所有包含这分词中的一个或多个的文档就会被搜索出来。
(2) term query: 代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇
GET /comet/_search
{
  "query": {
    "match": {
				"author": {"query": "心机"}
			}
  }
}
应该可以看到只写了部分字段也可以查询出数据
  • 有一天我们突然感觉 作者 这个字段 不太需要分词查询,想要搜索某个作者 精确查询就好了,如果只写了部分作者名称我们不希望搜索出来,这个时候我们需要新建一个索引
PUT comet_v2
{
 "settings": {
   "number_of_replicas": 0,
   "number_of_shards": 5,
   "index.store.type": "niofs",
   "index.query.default_field": "title",
   "index.unassigned.node_left.delayed_timeout": "5m"
 },

 "mappings": {
   "comet_v2": {
     "dynamic": "strict",
     "properties": {
       "cometId": {
         "type": "long"
       },
       "title": {
         "type": "text",
         "analyzer": "ik_smart",
         "search_analyzer": "ik_smart"
       },
       "author": {
          "type": "keyword"
       },
       "editor": {
         "type": "keyword"
       },
       "category": {
         "type": "keyword"
       },
       "description": {
         "type": "text",
         "analyzer": "ik_smart",
         "search_analyzer": "ik_smart"
       },
       "content": {
         "type": "text",
         "analyzer": "ik_smart",
         "search_analyzer": "ik_smart"
       },
       "createTime": {
         "type": "date",
         "format": "strict_date_optional_time||epoch_millis"
       },
       "suggest": {
         "type": "completion"
       }
     }
   }
 }
}
接下来我们需要把数据导入到这个新的索引,推荐使用之前api里面提到过的scan scroll方式

索引修改重新索引数据

    @Override
    public void reIndex(String originIndex, String newIndex) {
        //scroll 查询  批量插入
        try {

            final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices(originIndex);//设置指定的索引
            searchRequest.scroll(scroll);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(QueryBuilders.matchAllQuery());//查询所有
            searchSourceBuilder.size(1000);
            searchRequest.source(searchSourceBuilder);

            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            String scrollId = searchResponse.getScrollId();//获取第一次scrollId

            SearchHits searchHits=searchResponse.getHits();
            log.info("scrollId:{},total:{}",scrollId,searchHits.getTotalHits());
            SearchHit[] hits=searchHits.getHits();

            while (hits != null && hits.length > 0) {

                List<CometIndex> list = Lists.newArrayList();
                CometIndex cometIndex=null;
                for (SearchHit hit : hits) {
                    cometIndex=new CometIndex();
                    // do something with the SearchHit
                    Map<String, Object> sourceAsMap =  hit.getSourceAsMap();
                    //调用bulk
                    cometIndex.setTitle(sourceAsMap.getOrDefault(CometIndexKey.TITLE,"").toString());
                    cometIndex.setEditor(sourceAsMap.getOrDefault(CometIndexKey.EDITOR,"").toString());
                    cometIndex.setDescription(sourceAsMap.getOrDefault(CometIndexKey.DESCRIPTION,"").toString());
                    cometIndex.setContent(sourceAsMap.getOrDefault(CometIndexKey.CONTENT,"").toString());
                    cometIndex.setCreateTime(new Date());
                    cometIndex.setCategory(sourceAsMap.getOrDefault(CometIndexKey.CATEGORY,"").toString());

                    cometIndex.setCometId(Long.parseLong(sourceAsMap.get(CometIndexKey.COMET_ID).toString()));

                    cometIndex.setAuthor(sourceAsMap.getOrDefault(CometIndexKey.AUTHOR,"").toString());
                    list.add(cometIndex);
                }

                bulk(list,newIndex);

                log.info("scrollId:{}",scrollId);
                SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);//根据scrollId检索
                scrollRequest.scroll(scroll);
                searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
                scrollId = searchResponse.getScrollId();//获取下一次scrollId
                log.info("scrollId:{}",scrollId);
                hits = searchResponse.getHits().getHits();

            }
            //release the search context
            ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
            clearScrollRequest.addScrollId(scrollId);
            ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
            boolean succeeded = clearScrollResponse.isSucceeded();

            log.info("ScrollRequest result:{}",succeeded);
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    public void bulk(List<CometIndex> list,String indexName) {

        //批量插入数据
        BulkRequest request = new BulkRequest();

        try {
            for (CometIndex json:list){
                request.add(new IndexRequest(indexName, indexName)
                        .source(objectMapper.writeValueAsString(json), XContentType.JSON));
            }

            BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);

            //The Bulk response provides a method to quickly check if one or more operation has failed:
            if (bulkResponse.hasFailures()) {
                log.info("all success");
            }
            TimeValue took = bulkResponse.getTook();
            log.info("[批量新增花费的毫秒]:{},({}),{}", took, took.getMillis(), took.getSeconds());
            //所有操作结果进行迭代
            /*for (BulkItemResponse bulkItemResponse : bulkResponse) {
                if (bulkItemResponse.isFailed()) {
                    BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
                }
            }*/
        }catch (Exception e){
            e.printStackTrace();
        }

    }
  • 我们认为数据已经被正确的索引了,我们就将别名指向新的索引
别名可以指向多个索引,我们需要在新索引中添加别名的同时从旧索引中删除它。这个操作需要原子化,因此我们需要用 _aliases 操作:
POST /_aliases
{
    "actions": [
        { "remove": { "index": "comet_v1", "alias": "comet" }},
        { "add":    { "index": "comet_v2", "alias": "comet" }}
    ]
}   
然后继续搜索
GET /comet/_search
{
  "query": {
    "match": {
				"author": {"query": "心机"}
			}
  }
}

发现已经查询不到数据了,因为此时需要term query 精确搜索

GET /comet/_search  
{  
  "query": {  
    "term": {  
      "author": "心机boy"
    }  
  }  
}  
  • 最后测试成功后,此时我们就可以完全删除 comet_v1 索引了。
  • 完整代码后续会提供github,有问题可以留言讨论,或者私信。
打开App,阅读手记
3人推荐
发表评论
随时随地看视频慕课网APP