精华内容
下载资源
问答
  • 现在在很多都用到全文检索功能,概念就过了,这里我使用到了3个工具包 IKAnalyzer2012FF_u1.jar ...创建索引: /** * 创建索引 */ public static void createIndex(){ //创建需要建立索引的目录 File da

    现在在很多都用到全文检索功能,概念就过了,这里我使用到了3个工具包

    IKAnalyzer2012FF_u1.jar
    lucene-core-4.0.0.jar
    lucene-queryparser-4.0.0.jar

    创建索引:

    /**
    	 * 创建索引
    	 */
    	public static void createIndex(){
    		//创建需要建立索引的目录
    		File dataDir=new File("F:\\ToolPackage");
    		if(dataDir.exists()){
    			//获取文件数组
    			File[] dataDirs=dataDir.listFiles();
    			//创建目录
    			Directory directory=null;
    			//创建IndexWriter
    			IndexWriter indexWriter=null;
    			long startTime=System.currentTimeMillis();//记录开始创建索引时间
    			try {
    				directory=FSDirectory.open(new File(getIndexDir()));//打开索引文件存放目录
    				IndexWriterConfig iwConfig=new IndexWriterConfig(Version.LUCENE_40, new IKAnalyzer(true));//使用粗粒度分词
    				indexWriter=new IndexWriter(directory, iwConfig);//实例化IndexWriter
    				for(int i=0;i<dataDirs.length;i++){
    					//判断是否是文件并且文件后缀是否是.jar格式
    					if(dataDirs[i].isFile()&&dataDirs[i].getName().endsWith(".jar")){
    						System.out.println("Index File:"+dataDirs[i].getCanonicalPath());//打印出文件路径
    						Document document=new Document();//创建文档对象
    						document.add(new TextField("path", dataDirs[i].getName(),Store.YES));//对文件目录进行分词存储
    						document.add(new TextField("content", dataDirs[i].getCanonicalPath(),Store.YES));//对文件路径不分词存储
    						//将文档添加到IndexWriter中
    						indexWriter.addDocument(document);
    					}
    				}
    				//关闭资源
    				indexWriter.close();
    				directory.close();
    				long endTime=System.currentTimeMillis();//记录创建完成时间
    				System.out.println(endTime-startTime);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}else{
    			System.out.println("目录不存在");
    		}
    	}

    创建搜索:

    /**
    	 * 创建搜索
    	 * @param content
    	 * @return
    	 */
    	private static String createSearch(String content){
    		String result="";
    		try {
    			//打开所有文件目录
    			Directory directory=FSDirectory.open(new File(getIndexDir()));
    			IndexReader reader=IndexReader.open(directory);//创建索引读取器
    			IndexSearcher search=new IndexSearcher(reader);//创建索引搜索器
    			//TermQuery query=new TermQuery(new Term("path",content));//创建分词查询
    			//使用查询解析器创建Query对象
    			QueryParser parser=new QueryParser(Version.LUCENE_40, "path", new IKAnalyzer(true));
    			Query query=parser.parse(QueryParser.escape(content));//传入需要搜索的内容
    			TopDocs topDocs=search.search(query, 1);//检索得分最高的文档
    			if(topDocs.totalHits>0){
    				ScoreDoc[] scoreDoc=topDocs.scoreDocs;//获取分数文档数据
    				for(ScoreDoc doc:scoreDoc){//遍历分数文档
    					Document docu=search.doc(doc.doc);//获取文档对象
    					result=docu.get("content");//输出搜索到的信息
    				}
    			}
    			reader.close();//关闭索引读取器
    			directory.close();//关闭目录资源
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return result;
    	}
    索引文件创建在当前目录classes中的

    获取创建索引目录路径:

    /**
    	 * 获取索引创建目录
    	 * @return
    	 */
    	private static String getIndexDir(){
    		//得到.class文件所在的路径
    		String classPath=ClassLoader.getSystemClassLoader().getResource("").toString();
    		if(classPath.startsWith("file:/")){
    			classPath=classPath.replaceAll("file:/", "");
    		}
    		return classPath+"index";
    	}


    展开全文
  • 关于Lucene以及索引搜索的流程

    千次阅读 2016-04-06 15:02:23
     因此,你不需要深入理解Lucene的信息索引和检索工作方面的知识就可以开始使用。 Lucene提供了简单但是强大的核心API去实现全文索引和检索,你只需要掌握少数的类就能将Lucene整合到应用中。 刚接触Lucene的人...

    Lucene的普及和成功的背后是因为它的简单。

      因此,你不需要深入理解Lucene的信息索引和检索工作方面的知识就可以开始使用。

      Lucene提供了简单但是强大的核心API去实现全文索引和检索,你只需要掌握少数的类就能将Lucene整合到应用中。

      刚接触Lucene的人可能会误认为Lucene是一个文件搜索工具、网络爬虫、或者网页搜索引擎。实际上Lucene是一个软件库,而不是一个全功能的搜索应用程序。它涉及全文索引和搜索,而且做得非常好。Lucene可以让你的应用程序隐藏起复杂的索引和搜索背后的操作,而使用简单的API处理特定的问题领域和业务规则。你可以想象Lucene就是像一个层,你的应用就在层的上面。

      Lucene允许你添加索引和搜索功能到应用程序中。Lucene不关心数据的来源,Lucene可以索引和搜索任何可以转换成文本格式的数据。这意味着你可以用Lucene索引和搜索数据:远程web服务器上的网页、存储在本地文件系统的文档、简单的文本文件、Microsoft Word文档、HTML或PDF文件,或者其他任何可以从中提取文本信息的格式文件。

      所有搜索引擎的核心就是索引的概念:把原始数据处理成一个高效的交叉引用查找,以便快速检索。让我们看看快速高效的索引和搜索过程。

      1.索引是什么,为什么它这么重要?

      假如你需要搜索大量的文件,你希望找到那些包含某个单词或词组的文件。你将如何去写一个程序实现这个功能?一个做法就是按顺序扫描每一个文件,搜索是否包含给定的单词或词组。但是这样的做法有很多缺陷的,其中最明显的就是在大量的文件存在的情况下,速度是令人无法接受的。这种情况下,索引产生了。为了搜索大量的文本,你首先要对这些文本以特定的结构存储,这种存储结构可以让你迅速的搜索,消除慢的顺序扫描的过程。这种存储结构就叫索引,将文本转换成特定结构存储的过程,就叫建立索引。

      索引作为一种数据结构,允许你快速随机的访问存储在里面的词。类似于字典的目录,某个词对应到某一页,查找的时候直接定位到那一页,速度就非常快,不用一页一页的翻去查找。Lucene的索引是一种专门设计的数据结构,通常作为一组索引文件存储在文件系统上。

      2.什么是搜索?

      在索引中搜索关键词,找到包含关键词的文档的过程就是搜索。搜索质量通常使用准确度和召回率来描述。所谓召回率是指一次搜索结果集合中符合用户要求的数目与和用户查询相关的总数之比,而准确率是指一次搜索结果集合中符合用户要求的数目与该次搜索结果总数之比。我们也需要考虑其他有关搜索的因素,比如速度和快速搜索大量文本的能力,单个和多项查询、 短语查询、 通配符、 结果的排名和排序的支持也很重要。

      3.Lucene in Action

      假如我们需要索引和搜索存储在一个目录下的文件。

      在我们使用Lucene进行搜索之前,我们需要先建立索引。使用的Lucene的版本是3.6。

      3.1建立索引

      1)创建存放索引的目录Directory

      2)创建索引器配置管理类IndexWriterConfig

      3)使用索引目录和配置管理类创建索引器

      4)使用索引器将Document写到索引文件中

      索引器类:
      

        /**
     * 索引器
     * @author Luxh
     */
    public class Indexer {
    
    
        /**
         * 建立索引
         * @param filePath 需要建立索引的文件的存放路径
         * @throws IOException
         */
        public static void createIndex(String filePath) throws IOException {
    
            //在当前路径下创建一个叫indexDir的目录
            File indexDir = new File("./indexDir");
    
            //创建索引目录
            Directory directory = FSDirectory.open(indexDir);
    
            //创建一个分词器
            Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
    
            //创建索引配置器
            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_36,analyzer);
    
    
            LogMergePolicy mergePolicy = new LogByteSizeMergePolicy();
    
            //设置segment添加文档(Document)时的合并频率
            //值较小,建立索引的速度就较慢
            //值较大,建立索引的速度就较快,>10适合批量建立索引
            mergePolicy.setMergeFactor(50);
    
            //设置segment最大合并文档(Document)数
            //值较小有利于追加索引的速度
            //值较大,适合批量建立索引和更快的搜索
            mergePolicy.setMaxMergeDocs(5000);
    
            //启用复合式索引文件格式,合并多个segment
            mergePolicy.setUseCompoundFile(true);
    
    
            indexWriterConfig.setMergePolicy(mergePolicy);
    
            //设置索引的打开模式
            indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
    
            //创建索引器
            IndexWriter indexWriter = new IndexWriter(directory,indexWriterConfig);
    
    
            File fileDir = new File(filePath);
            for(File file : fileDir.listFiles()) {
                //Document是Lucene的文档结构,需要索引的对象都要转换为Document
                Document document = new Document();
    
                //文件名,可查询,分词,存储到索引库记录中
                document.add(new Field("name",getFileName(file),Store.YES,Index.ANALYZED));
    
                //文件路径,可查询,不分词,存储到索引库记录中
                document.add(new Field("path",file.getAbsolutePath(),Store.YES,Index.NOT_ANALYZED));
    
                //大文本内容,可查询,不存储,实际上可根据文件路径去找到真正的文本内容
                //document.add(new Field("content",new FileReader(file)));
    
                //小文本内容,可以存储到索引记录库
                document.add(new Field("content",getFileContent(file),Store.YES,Index.ANALYZED));
    
                //把文档添加到索引库
                indexWriter.addDocument(document);
    
            }
    
            //提交索引到磁盘上的索引库,关闭索引器
            indexWriter.close();
    
        }
    
        /**
         * 获取文件名
         */
        public static String getFileName(File file) {
            String fileName = "";
            if(file != null) {
                fileName = file.getName().substring(0, file.getName().lastIndexOf("."));
            }
            return fileName;
        }
    
        /**
         * 获取文本
         * @param file
         */
        public static String getFileContent(File file) {
            FileReader fr = null;
            BufferedReader br = null;
            String content = "";
            try {
                fr = new FileReader(file);
                br = new BufferedReader(fr);
                StringBuffer sb = new StringBuffer();
                String line = br.readLine();
                while(null != line){
                    sb.append(line);
                    line = br.readLine();
                }
                content = sb.toString();
            }catch(Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    if(fr != null)
                        fr.close();
                    if(br != null)
                        br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return content;
    
        }
    
    
    }

    IndexWriter:索引器,负责创建和维护一条索引。

      在Lucene3.6版本,只推荐使用一个构造方法IndexWriter(Directory d,IndexWriterConfig conf),其他的构造方法都已经过时。所有关于IndexWriter的配置都是通过IndexWriterConfig来进行管理。

      IndexWriterConfig:索引器配置类,管理所有有关索引器的配置。只有一个构造方法IndexWriterConfig(Version matchVersion,Analyzer analyzer),构造方法中的参数matchVersion是Lucene的版本,analyzer是分词器。

      接下来我们运行索引器创建索引。
      

    public class TestIndexer {
    
        /**
         * 创建索引
         * @throws IOException
         */
        @Test
        public void testCreateIndex() throws IOException{
            //存放需要建立索引的文件的目录路径
            String filePath = "./fileDir";
            //调用索引器的创建索引方法
            Indexer.createIndex(filePath);
        }
    }

    这样我们就对当前路径下fileDir中的文件创建了索引。

      3.2执行搜索

      在Lucene中搜索像建立索引一样简单、快速。现在,我们建立一个搜索器,搜索包含特定文本的文件。

      1)使用QueryParser将查询的关键词解析成Lucene的查询对象Query。创建QueryParser的时候我们需要用到分词器,这个分词器要和前面创建索引的时候使用的分词器一致。

      2)使用FSDirectory打开索引所在的目录。

      3)使用IndexReader读取索引目录和使用IndexSearcher进行搜索。

      4)返回搜索结果对象TopDocs。TopDocs包含搜索到结果总数和结果的集合ScoreDocs数组

      5)遍历结果的集合ScoreDocs数组,根据每一个ScoreDoc的文档编号获取Document

      看看搜索器的代码:
      

    /**
     * 搜索器
     * @author Luxh
     */
    public class Searcher {
    
        /**
         * 搜索
         * @param keyWord 搜索的关键词
         * @param indexDir  索引目录所在路径
         * @throws ParseException
         * @throws IOException
         * @return List<Document>
         */
        public static List<Document> search(String keyWord,String indexDirPath) throws ParseException, IOException {
    
            String[] fields = {"name","content"};
    
            //创建一个分词器,和创建索引时用的分词器要一致
            Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
    
            //创建查询解析器
            QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_36,fields,analyzer);
    
            //将查询关键词解析成Lucene的Query对象
            Query query = queryParser.parse(keyWord);
    
            //打开索引目录
            File indexDir = new File(indexDirPath);
            Directory directory = FSDirectory.open(indexDir);
    
            //获取访问索引的接口,进行搜索
            IndexReader indexReader  = IndexReader.open(directory);
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    
            //TopDocs 搜索返回的结果
            TopDocs topDocs = indexSearcher.search(query, 100);//只返回前100条记录
    
            int totalCount = topDocs.totalHits; // 搜索结果总数量
            System.out.println("搜索到的结果总数量为:" + totalCount);
    
            ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 搜索的结果集合
    
            List<Document> docs = new ArrayList<Document>();
    
            for(ScoreDoc scoreDoc : scoreDocs) {
                //文档编号
                int docID = scoreDoc.doc;
                //根据文档编号获取文档
                Document doc = indexSearcher.doc(docID);
                docs.add(doc);
            }
            indexReader.close();
            indexSearcher.close();
            return docs;
        }
    }

    接下来我们运行搜索器:

    public class TestSearcher {
    
        /**
         * 搜索
         */
        @Test
        public void testSearch() throws IOException, ParseException{
            //搜索关键词
            String keyWord = "Java";
            //索引目录路径
            String indexDirPath = "./indexDir";
            //调用搜索器进行搜索
            List<Document> docs = Searcher.search(keyWord, indexDirPath);
            for(Document doc : docs) {
                System.out.println("文件名 : "+doc.get("name"));
                System.out.println("路径 : "+doc.get("path"));
                System.out.println("内容 : "+doc.get("content"));
            }
        }
    
    
    }

    如果有包含关键词的文件,就会被搜索出来了。

    展开全文
  • 文章目录创建索引指定分片创建指定mapping创建指定别名创建返回结果说明删除索引查看索引定义信息修改索引的settings信息打开/关闭索引索引模板创建索引模板查看索引模板删除索引模板索引监控查看索引状态信息查看...

    官网索引介绍:https://www.elastic.co/guide/en/elasticsearch/reference/current/indices.html

    创建索引

    指定分片创建

    PUT twitter {
        "settings" : {
            "index" : {
                "number_of_shards" : 3, 
                "number_of_replicas" : 2 
            }
        }
    }
    

    或者简单的写为:

    PUT twitter {
        "settings" : {
            "number_of_shards" : 3,
            "number_of_replicas" : 2
        }
    }
    
    • number_of_shards:表示分片数,默认5,最大1024
    • number_of_replicas:每个分片的备份数,默认1

    指定mapping创建

    PUT test {
        "settings" : {
            "number_of_shards" : 1
        },
        "mappings" : {
            "_doc" : {
                "properties" : {
                    "field1" : { "type" : "text" }
                }
            }
        }
    }
    

    指定别名创建

    PUT test {
        "aliases" : {
            "alias_1" : {},
            "alias_2" : {
                "filter" : {
                    "term" : {"user" : "kimchy" }
                },
                "routing" : "kimchy"
            }
        }
    }
    

    返回结果说明

    {
        "acknowledged": true,
        "shards_acknowledged": true,
        "index": "test"
    }
    
    • acknowledged:true表示索引创建成功
    • shards_acknowledged:所需数量的分片+副本启动成功
    • 以上两个值也会返回false,如果没有返回错误信息,则表示等待时间到了超时时间就直接返回了

    删除索引

    DELETE /twitter  #删除单个索引
    DELETE /twitter1,twitter2  #删除多个索引
    DELETE /twitter*  #通配符,删除twitter开头的索引
    DELETE /_all  #删除所有索引,慎用!
    DELETE /*  #删除所有索引,慎用!
    

    注意:无法通过索引的别名进行删除索引

    查看索引定义信息

    GET /twitter  #查看twitter索引的所有定义信息
    GET /twitter/_settings  #查看该索引的_settings部分的定义
    GET /twitter/_mapping  #查看该索引的_mapping部分的定义
    HEAD twitter  #404表示不存在,200表示存在
    

    修改索引的settings信息

    索引的设置信息分为静态信息和动态信息两部分,静态信息不可更改,如索引的分片数,而动态信息可以修改。详细的设置项请参考官网:
    https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-modules-settings


    修改twitter索引的备份数:

    PUT /twitter/_settings {
        "index" : {
            "number_of_replicas" : 2
        }
    }
    
    • PUT /_settings:更新所有索引的_settings
    • PUT /{index}/_settings:更新一个或多个索引的_settings

    设置回默认值,用null

    PUT /twitter/_settings {
        "index" : {
            "refresh_interval" : null
        }
    }
    

    设置索引的读写

    index.blocks.read_only:设为true,则索引以及索引的元数据只可读
    index.blocks.read_only_allow_delete:设为true,只读时允许删除
    index.blocks.read:设为true,则不可读
    index.blocks.write:设为true,则不可写
    index.blocks.metadata:设为true,则索引元数据不可读写
    

    打开/关闭索引

    关闭的索引不能进行读写操作,几乎不占集群开销。
    关闭的索引可以打开,打开走的是正常的恢复流程。

    POST /my_index/_close
    POST /my_index/_open
    

    索引模板

    创建索引模板

    在创建索引时,为每个索引写定义信息可能是一件繁琐的事情,特别是如果有相同的settings、mapping等。

    ES提供了索引模板功能,让你可以定义一个索引模板,模板中定义好settings、mapping、以及一个模式定义来匹配创建的索引。

    模板只在索引创建时被参考,修改模板不会影响已创建的索引。

    定义一个模板:

    PUT _template/template_1 {
      "index_patterns": ["te*", "bar*"],
      "settings": {
        "number_of_shards": 1
      },
      "mappings": {
        "type1": {
          "_source": {
            "enabled": false
          },
          "properties": {
            "host_name": {
              "type": "keyword"
            },
            "created_at": {
              "type": "date",
              "format": "EEE MMM dd HH:mm:ss Z YYYY"
            }
          }
        }
      }
    }
    
    • 定义了一个名称为template_1的索引模板
    • index_patterns:指定了哪些索引会使用该模板,允许通配符格式。这里表示创建索引是,te或bar开头的索引会使用该模板

    查看索引模板

    GET /_template/template_1
    GET /_template/temp*
    GET /_template/template_1,template_2
    GET /_template
    

    删除索引模板

    DELETE /_template/template_1
    

    索引监控

    查看索引状态信息

    官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-stats.html

    GET /_stats
    GET /index1/_stats
    GET /index1,index2/_stats
    

    查看索引段信息

    官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-segments.html

    GET /_segments
    GET /index1/_segments
    GET /index1,index2/_segments
    

    查看索引恢复信息

    官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-recovery.html

    GET /_recovery?human
    GET index1,index2/_recovery?human
    

    查看索引分片存储的信息

    官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-shards-stores.html

    GET /index1/_shard_stores
    GET /index1,index2/_shard_stores
    GET /_shard_stores
    GET /_shard_stores?status=green
    

    索引状态管理

    清理缓存

    POST /index1/_cache/clear
    POST /index1,index2/_cache/clear 
    POST /_cache/clear
    

    刷新

    POST /index1/_refresh
    POST /index1,index2/_refresh
    POST /_refresh
    

    Flush内存数据持久化

    POST index1/_flush/
    

    强制段合并

    POST /index1/_forcemerge?only_expunge_deletes=false&max_num_segments=100&flush=true
    POST /index1,index2/_forcemerge
    POST /_forcemerge
    
    • only_expunge_deletes:是否只合并含有删除文档的段,默认false
    • max_num_segments:合并为几个段,默认1
    • flush:合并后是否刷新,默认true

    索引别名

    如果希望一次查询可查询多个索引,如果希望通过索引的视图来操作索引,就像数据库库中的视图一样,就可以使用索引别名。

    索引的别名机制,就是让我们可以以视图的方式来操作集群中的索引,这个视图可是多个索引,也可是一个索引或索引的一部分。

    创建别名

    POST /_aliases
    {
        "actions" : [
            { "add" : { "index" : "test1", "alias" : "alias1" } }
        ]
    }
    

    删除索引

    POST /_aliases
    {
        "actions" : [
            { "remove" : { "index" : "test1", "alias" : "alias1" } }
        ]
    }
    

    批量新增索引

    POST /_aliases
    {
        "actions" : [
            { "remove" : { "index" : "test1", "alias" : "alias1" } },
            { "add" : { "index" : "test2", "alias" : "alias1" } }
        ]
    }
    

    为多个索引定义别名

    方式一:

    POST /_aliases
    {
        "actions" : [
            { "add" : { "index" : "test1", "alias" : "alias1" } },
            { "add" : { "index" : "test2", "alias" : "alias1" } }
        ]
    }
    

    方式二:

    POST /_aliases
    {
        "actions" : [
            { "add" : { "indices" : ["test1", "test2"], "alias" : "alias1" } }
        ]
    }
    

    方式三(通配符):

    POST /_aliases
    {
        "actions" : [
            { "add" : { "index" : "test*", "alias" : "all_test_indices" } }
        ]
    }
    

    注意:在这种情况下,别名是一个时间点的别名,它将对所有匹配的当前索引进行别名,当添加/删除与此模式匹配的新索引时,它不会自动更新

    带过滤器的别名

    过滤器通过Query DSL来定义,将作用于通过该别名来进行的所有Search, Count, Delete By Query and More Like This 操作。

    第一步:首先索引中需要有字段

    PUT /test1
    {
      "mappings": {
        "type1": {
          "properties": {
            "user" : {
              "type": "keyword"
            }
          }
        }
      }
    }
    

    第二步:增加带有过滤器的索引

    POST /_aliases
    {
        "actions" : [
            {
                "add" : {
                     "index" : "test1",
                     "alias" : "alias2",
                     "filter" : { "term" : { "user" : "kimchy" } }
                }
            }
        ]
    }
    

    带路由(指定分片)的别名

    可在别名定义中指定路由值,可和filter一起使用,用来限定操作的分片,避免不需要的其他分片操作。

    指定带有路由分片的别名,查询、索引都指向该分片:

    POST /_aliases
    {
        "actions" : [
            {
                "add" : {
                     "index" : "test",
                     "alias" : "alias1",
                     "routing" : "1"
                }
            }
        ]
    }
    

    为搜索、索引指定不同的路由分片:

    POST /_aliases
    {
        "actions" : [
            {
                "add" : {
                     "index" : "test",
                     "alias" : "alias2",
                     "search_routing" : "1,2",
                     "index_routing" : "2"
                }
            }
        ]
    }
    

    以PUT方式来定义一个索引

    PUT /{index}/_alias/{name}
    
    PUT /logs_201305/_alias/2013
    
    PUT /users
    {
        "mappings" : {
            "user" : {
                "properties" : {
                    "user_id" : {"type" : "integer"}
                }
            }
        }
    }
    
    PUT /users/_alias/user_12
    {
        "routing" : "12",
        "filter" : {
            "term" : {
                "user_id" : 12
            }
        }
    }
    

    查看别名定义信息

    GET /{index}/_alias/{alias}
    GET /logs_20162801/_alias/*
    GET /_alias/2016
    GET /_alias/20*
    

    Shrink Index 收缩索引

    索引的分片数是不可更改的,如要减少分片数可以通过收缩方式收缩为一个新的索引。

    新索引的分片数必须是原分片数的因子值,如原分片数是8,则新索引的分片数可以为4、2、1 。

    • 先把所有主分片都转移到一台主机上,即确保一台主机上有该索引的所有数据
    • 在这台主机上创建一个新索引,分片数较小,其他设置和原索引一致
    • 把原索引的所有分片,复制(或硬链接)到新索引的目录下
    • 对新索引进行打开操作恢复分片数据
    • (可选)重新把新索引的分片均衡到其他节点上

    收缩前的准备工作:

    • 将原索引设置为只读
    • 将原索引各分片的一个副本重分配到同一个节点上,并且要是健康绿色状态

    以上两个步骤可以通过以下命令达成:

    PUT /my_source_index/_settings {
      "settings": {
        "index.routing.allocation.require._name": "shrink_node_name", 
        "index.blocks.write": true
      }
    }
    
    • shrink_node_name:新的es节点,即将原索引各分片的一个副本重新分配到该节点上
    • index.blocks.write:阻止写操作,只读

    进行收缩:

    POST my_source_index/_shrink/my_target_index {
      "settings": {
        "index.number_of_replicas": 1,
        "index.number_of_shards": 1, 
        "index.codec": "best_compression" 
      }}
    
    

    监控收缩状态:

    GET _cat/recovery?v
    GET _cluster/health
    

    Split Index 拆分索引

    当索引的每个分片数据容量过大时,需要增加分片数量,则可以通过拆分操作将索引拆分为一个倍数分片数的新索引。

    能拆分为几倍由创建索引时指定的index.number_of_routing_shards 路由分片数决定。这个路由分片数决定了根据一致性hash路由文档到分片的散列空间。

    如index.number_of_routing_shards = 30 ,指定的分片数是5,则可按如下倍数方式进行拆分:

    • 5 → 10 → 30 (split by 2, then by 3)
    • 5 → 15 → 30 (split by 3, then by 2)
    • 5 → 30 (split by 6)
    • 拆分的数量必须为分片数的倍数,且为index.number_of_routing_shards的因子

    注意:只有在创建时指定了index.number_of_routing_shards 的索引才可以进行拆分,ES7开始将不再有这个限制


    准备一个索引来做拆分

    PUT my_source_index {
        "settings": {
            "index.number_of_shards" : 1,
            "index.number_of_routing_shards" : 8 
        }
    }
    

    先设置索引只读:

    PUT /my_source_index/_settingsc{
      "settings": {
        "index.blocks.write": true 
      }
    }
    

    拆分:

    POST my_source_index/_split/my_target_index {
      "settings": {
        "index.number_of_shards": 2
      }
    }
    

    监控拆分过程:

    GET _cat/recovery?v
    GET _cluster/health
    

    Rollover Index 别名滚动

    对于有时效性的索引数据,如日志,过一定时间后,老的索引数据就没有用了。

    我们可以像数据库中根据时间创建表来存放不同时段的数据一样,在ES中也可用建多个索引的方式来分开存放不同时段的数据。

    比数据库中更方便的是ES中可以通过别名滚动指向最新的索引的方式,让你通过别名来操作时总是操作的最新的索引。


    ES的rollover index API 让我们可以根据满足指定的条件(时间、文档数量、索引大小)创建新的索引,并把别名滚动指向新的索引。

    注意:这时的别名只能是一个索引的别名

    示例:

    PUT /logs-000001  {
      "aliases": {
        "logs_write": {}
      }
    }
    
    # Add > 1000 documents to logs-000001
    
    POST /logs_write/_rollover {
      "conditions": {
        "max_age":   "7d",
        "max_docs":  1000,
        "max_size":  "5gb"
      }
    }
    
    • 创建一个名字为logs-000001、别名为logs_write的索引
    • conditions:指定如果别名logs_write指向的索引是7天前(含)创建的或索引的文档数>=1000或索引的大小>= 5gb,则会创建一个新索引 logs-000002,并把别名logs_writer指向新创建的logs-000002索引

    命名规则:

    • 如果索引的名称是-数字结尾,如logs-000001,则新建索引的名称也会是这个模式,数值增1。
    • 如果索引的名称不是-数值结尾,则在请求rollover api时需指定新索引的名称:
    POST /my_alias/_rollover/my_new_index_name {
      "conditions": {
        "max_age":   "7d",
        "max_docs":  1000,
        "max_size": "5gb"
      }
    }
    

    在索引名称中使用Date math时间表达式

    如果你希望生成的索引名称中带有日期,如logstash-2016.02.03-1 ,则可以在创建索引时采用时间表达式来命名:

    # PUT /<logs-{now/d}-1> with URI encoding:
    PUT /%3Clogs-%7Bnow%2Fd%7D-1%3E 
    {
      "aliases": {
        "logs_write": {}
      }
    }
    
    PUT logs_write/_doc/1
    {
      "message": "a dummy log"
    }
    
    POST logs_write/_refresh
    
    # Wait for a day to pass
    
    POST /logs_write/_rollover 
    {
      "conditions": {
        "max_docs":   "1"
      }
    }
    

    Rollover时可对新的索引作定义:

    PUT /logs-000001
    {
      "aliases": {
        "logs_write": {}
      }
    }
    
    POST /logs_write/_rollover
    {
      "conditions" : {
        "max_age": "7d",
        "max_docs": 1000,
        "max_size": "5gb"
      },
      "settings": {
        "index.number_of_shards": 2
      }
    }
    

    可以在实际的rollover操作前先来一个排练,使用dry_run命令,排练不会创建索引,只是检测条件是否满足

    POST /logs_write/_rollover?dry_run
    {
      "conditions" : {
        "max_age": "7d",
        "max_docs": 1000,
        "max_size": "5gb"
      }
    }
    

    注意:rollover是你请求它才会进行操作,并不是自动在后台进行的。你可以周期性地去请求它

    展开全文
  • 基于lucene的案例开发:搜索索引

    千次阅读 2015-01-19 22:06:13
    通过简单的事例介绍了如何去搜索Lucene索引,同时还介绍了索引搜索过程中的几个核心类:Directory、DirectoryReader、IndexSearcher、Analyzer、Query、TopDocs

    转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/42884921

          此事例中的索引数据来自于上一篇博客创建的索引,索引中包含两篇文档,每一篇文档中有两个域 name 、 content 。


    索引搜索demo

          还是老样子在介绍之前先看一个简单索引搜索 demo程序。

     /**  
     *@Description:  索引检索demo
     */ 
    package com.lulei.lucene.study;  
    
    import java.io.File;
    
    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.standard.StandardAnalyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.index.DirectoryReader;
    import org.apache.lucene.queryparser.classic.QueryParser;
    import org.apache.lucene.search.IndexSearcher;
    import org.apache.lucene.search.Query;
    import org.apache.lucene.search.TopDocs;
    import org.apache.lucene.store.Directory;
    import org.apache.lucene.store.FSDirectory;
    import org.apache.lucene.util.Version;
      
    public class SearchIndex {
    
    	public static void main(String[] args) {
    		Directory directory = null;
    		try {
    			//索引硬盘存储路径
    			directory = FSDirectory.open(new File("D://study/index/testindex"));
    			//读取索引
    			DirectoryReader dReader = DirectoryReader.open(directory);
    			//创建索引检索对象
    		    IndexSearcher searcher = new IndexSearcher(dReader);
    		    //指定分词技术,这里采用的语言处理模块要和创建索引的时候一致,否则检索的结果很不理想
    		    Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43);
    		    //创建查询query,搜索词为“空间向量”
    		    QueryParser parse = new QueryParser(Version.LUCENE_43, "content", analyzer);
    			Query query = parse.parse("空间向量");
    			//检索索引,获取符合条件的前10条记录
    			TopDocs topDocs = searcher.search(query, 10);
    			if (topDocs != null) {
    				System.out.println("总共查找到 " +  topDocs.totalHits + " 条符合条件的记录");
    				//循环输出记录内容
    				for (int i = 0; i < topDocs.scoreDocs.length; i++) {
    					Document doc = searcher.doc(topDocs.scoreDocs[i].doc);
    					System.out.println("第" + (i + 1) + "条内容为--\tname:\t" + doc.get("name") + "\tcontent:\t" + doc.get("content"));
    				}
    			}
    			//关闭资源
    			dReader.close();
    			directory.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }


    上述demo程序运行结果截图如下:



          可以看出关键词 “空间向量” 的搜索结果为索引中的第二个文档,可以通过document.get方法可以获取对应的域值。


    搜索索引核心类

          在上述索引搜索过程中,用到了几个核心类:DirectoryDirectoryReaderIndexSearcherAnalyzerQueryTopDocs,上一篇介绍过的核心类这里就不再继续介绍了,这里就介绍一下之前没有介绍过的类。


    DirectoryReader

          DirectoryReader用于读取索引,创建的dReader对象用于创建用于搜索的IndexSearcher对象。

    IndexSearcher

          IndexSearcher用于索引的搜索,这个类公开了几个搜索方法,它是连接索引的中心环节;可以将IndexSearcher类看做成一个以只读打开索引的类,关于IndexSearcher的更深层次的内容,将在后面博客中介绍。

    Query

          Lucene中含有许多具体Query(查询)子类,Query子类有:TermQuery、BooleanQuery、PhraseQuery、PrefixQuery、PhrasePrefixQuery、TermRangQuery、NumericRangeQuery、FilteredQuery、SpanQuery等,这些子类也将会在以后的博客中一一介绍。

    TopDocs

          TopDocs类是一个简单的指针容器,指针一般指向前N个排名的搜索结果,搜索结果即匹配查询条件的文档。


          到目前为止,我们可以用Lucene实现一个简单的索引创建、搜索事例,在后面的几篇博客中,我将会逐一介绍分词技术、Query众多子类、IndexSearcher的搜索API等,这几部分可以通过源代码的阅读来理解。

    展开全文
  • sudo mdutil -i off /该命令用来关闭索引sudo mdutil -E /该命令用来删除索引sudo mdutil -i on /该命令用来重建索引然后用快捷键呼出spotlight菜单,随便输入一个词,就能看到提示,正在进行索引,并且告诉你重建...
  • lucene搜索索引

    2014-03-07 16:11:37
    //打开索引 IndexReader indexReader = IndexReader.open(FSDirectory.open(new File("C:\\suoyin"))); //搜索索引 IndexSearcher indexSearcher = new IndexSearcher(indexReader); //构建query ...
  • Lucene以及索引搜索的流程 Lucene的普及和成功的背后是因为它的简单。  因此,你不需要深入理解Lucene的信息索引和检索工作方面的知识就可以开始使用。  Lucene提供了简单但是强大的核心API去实现...
  • API索引搜索问题

    2014-05-07 23:35:46
    (1)chm文件和MSDN无法打开 下午不知卸载了啥,导致chm文件打不开,MSDN也打不开,报错“Can't Open C:/Program Files/Microsoft Visual Studio/MSDN/2001OCT/1033/MSDN130.COL”。看了这篇博文,在命令行运行...
  • 索引或者查询时提示:ERROR: invalid token in 配置文件 line 1 col 1.: 该提示表示当前的配置文件的编码不是UTF-8(无BOM头)格式,无法正确解析,请使用编辑软件打开配置文件,另存为UTF-8(无BOM头)格式; ...
  • lucene全文搜索之一中讲解了lucene开发搜索服务的基本结构,本章将会讲解如何创建索引器、管理索引目录和中文分词器的使用。 包括标准分词器,IKAnalyzer分词器以及两种索引目录的创建 luncene5.5.3集合jar包下载...
  • 原标题:让您电脑搜索查找更方便!...但如果在电脑上建立索引条目的话,系统便会根据索引进行搜索,加快了搜索速度,那就避免搜索耗时长的问题。Win10系统如何建立索引呢?下面小编就分享下具体的操作步骤。...
  • 简单说两句,Lucene现在高版本的教程很少...大致说一下Lucene就是通过创建索引这个类似书目录那样的东西来提升查询效率的一个框架,所谓索引我理解就是将文档等数据源的不同组成部分的指示标志,索引会指引使用者快速找
  • 问题 在处理elasticsearch的时候,通常需要不断地调整...后来才发现需要先关闭索引,然后再打开才能生效。   过程 下面是我的过程: 创建索引:   curl -XPUT http://localhost:9200/analyzetest/ -d ' ...
  • Lucence打开一个IndexReader和IndexSearcher后需要关闭吗? 不关闭的话可以更新索引吗?
  • 我们都是将IndexWriter 和 IndexSearch做成单例模式,这时会出现一种现象:即使IndexWriter.commit(),在IndexSearch查找依然查找不到最新添加的索引,这是因为IndexRead没有重新打开的问题,解决方法(关闭Index...
  • 索引应用二分查找算法快速定位索引项。 难得的是,Kafka的索引组件中应用了二分查找算法,而且社区还针对Kafka自身的特点对其进行了改良。 索引类图及源文件组织架构 都位于core包的/src/main/scala/kafka/log ...
  • 新增索引 PUT /nba获取索引 get /nba删除索引 delete /nba批量获取索引 GET /nba,nbb获取所有...执行完成以后,再获取索引,可发现"verified_before_close" : "true",就表示索引已经关闭打开指定的索引 post /nb...
  • 在某些时候可以将一个Document与一个物理文件进行对应,用一个Document来代替一个物理文件,然而更多的时候,Document和物理的文件没有关系,它作为一种数据源的集合,向Lucene提供原始的要索引
  • 搜索引擎之内存映射快速索引文件

    千次阅读 2009-07-01 12:01:00
    搜索引擎之利用内存映射快速索引文件 用户在通过关键字检索信息时,如果反馈的内容在3S之内是适度范围,如果10s了一般用户就会感觉难以忍受了,所以如何提高对用户的反馈速度就成了搜索引擎技术中一个瓶颈. 每天都会...
  • 本次故障原因:上一次关机未关闭代理软件,导致小娜联网出现问题 1、关闭代理软件 2、Win+X键以管理员身份运行powershell 3、输入以下;回车即重启小娜 Get - AppXPackage - Name Microsoft . Windows . ...
  • Zettair是一个基于倒排序索引结构的全文搜索开源引擎,由RMIT墨尔本皇家理工大学开源实现的。搜索引擎通常都是建立在一个特殊的结构之上的,称之为倒排序索引,这样可以快速响应查询。但是这样对于查询存在两个缺点...
  • Mac重建聚焦索引

    千次阅读 2019-07-30 08:51:39
    很多时候聚焦索引(command+空格)搜索不到任何关于本机的任何文件,甚至直接给你词典翻译,不是我们预期的效果,第一种情况,你可能禁用了spotlight的服务,需要重启服务;第二种情况,索引失效,所以有时候需要...
  • MySQL索引

    千次阅读 2016-09-16 23:19:28
    使用索引(1)对于创建的多列索引,只要查询的条件中用到了最左边的列,索引一般就会被使用。 (2)对于使用like 的查询,后面如果是常量并且只有%号不在第一个字符,索引才可能会 被使用。 注:前置位字符数量...
  • 一:环境:eclipse+lucene-core-3.5.0.jar+lucene-...为了对文档进行索引,Lucene 提供了五个基础的类,他们分别是 Document, Field, IndexWriter, Analyzer, Directory。下面我们分别介绍一下这五个类的用途: Docu
  • Win7之家(www.win7china.com):软媒原创:为Windows7建立索引搜索文件更给力也许你还记得XP时代搜索文件时出现的那只黄色的小狗狗,在Windows7时代,搜索变得更加快捷顺手,搜索栏就在那里,不点不搜。但其实...
  • Windows10自带的索引功能还是有些鸡肋,搜索速度一直上不去,还会占用系统资源(不低啊)。特别是使用了Everything等第三方快速搜索工具的朋友,就不会再用Win10自身的搜索功...
  • Elasticsearch 5.4 Indices(索引) API

    千次阅读 2017-06-15 22:19:01
    5 关闭打开索引 6 索引收缩 7 翻滚索引 二mapping管理 1 设置mapping 2 查看mapping 3 获取字段mapping 4 类型是否存在 三别名管理 1 索引别名设置 四索引配置 1 获取索引设置 2 更新索引设置 3 分析器 4 索引模板 ...
  • (1)chm文件和MSDN无法打开 下午不知卸载了啥,导致chm文件打不开,MSDN也打不开,报错“Cant Open C:/Program Files/Microsoft Visual Studio/MSDN/2001OCT/1033/MSDN130.COL”。看了这篇博文,在命令行运行regsvr...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 64,763
精华内容 25,905
关键字:

关闭索引打开搜索