Lucene详解

一.lucene原理

    Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。lucene 能够为文本类型的数据建立索引,所以你只要能把你要索引的数据格式转化的文本的,Lucene 就能对你的文档进行索引和搜索。比如你要对一些 HTML 文档,PDF 文档进行索引的话你就首先需要把 HTML 文档和 PDF 文档转化成文本格式的,然后将转化后的内容交给 Lucene 进行索引,然后把创建好的索引文件保存到磁盘或者内存中,最后根据用户输入的查询条件在索引文件上进行查询。

搜索应用程序和 Lucene 之间的关系,也反映了利用 Lucene 构建搜索应用程序的流程:

二. 索引和搜索

   索引是现代搜索引擎的核心,建立索引的过程就是把源数据处理成非常方便查询的索引文件的过程。为什么索引这么重要呢,试想你现在要在大量的文档中搜索含有某个关键词的文档,那么如果不建立索引的话你就需要把这些文档顺序的读入内存,然后检查这个文章中是不是含有要查找的关键词,这样的话就会耗费非常多的时间,想想搜索引擎可是在毫秒级的时间内查找出要搜索的结果的。这就是由于建立了索引的原因,你可以把索引想象成这样一种数据结构,他能够使你快速的随机访问存储在索引中的关键词,进而找到该关键词所关联的文档。Lucene 采用的是一种称为反向索引(inverted index)的机制。反向索引就是说我们维护了一个词 / 短语表,对于这个表中的每个词 / 短语,都有一个链表描述了有哪些文档包含了这个词 / 短语。这样在用户输入查询条件的时候,就能非常快的得到搜索结果。搜索引擎首先会对搜索的关键词进行解析,然后再在建立好的索引上面进行查找,最终返回和用户输入的关键词相关联的文档。对于中文用户来说,最关心的问题是其是否支持中文的全文检索。由于Lucene良好架构设计,对中文的支持只需对其语言词法分析接口进行扩展就能实现对中文检索的支持。

三. 索引步骤

  1. 获取内容: Lucene本身没有提供获取内容的工具或者组件,内容是要开发者自己提供相应的程序。这一步包括使用网络爬虫或蜘蛛程序来搜索和界定需要索引的内容。当然,数据来源可能包括数据库、分布式文件系统、本地xml等等。lucene作为一款核心搜索库,不提供任何功能来实现内容获取。目前有大量的开源爬虫软件可以实现这个功能,例如:Solr,lucene的子项;Nutch,apache项目,包含大规模的爬虫工具,抓取和分辨web站点数据;Grub,比较流行的开源web爬虫工具;Heritrix,一款开源的Internet文档搜索程序;Aperture,支持从web站点、文件系统和邮箱中抓取,并解析和索引其中的文本数据。
  2. 建立文档:获取原始内容后,需要对这些内容进行索引,必须将这些内容转换成部件(文档)。文档主要包括几个带值的域,比如标题,正文,摘要,作者和链接。如果文档和域比较重要的话,还可以添加权值。设计完方案后,需要将原始内容中的文本提取出来写入各个文档,这一步可以使用文档过滤器,开源项目如Tika,实现很好的文档过滤。如果要获取的原始内容存储于数据库中,有一些项目通过无缝链接内容获取步骤和文档建立步骤就能轻易地对数据库表进行航所以操作和搜索操作,例如DBSight,Hibernate Search,LuSQL,Compass和Oracle/Lucene集成项目。
  3. 文档分析: 搜索引擎不能直接对文本进行索引:必须将文本分割成一系列被称为语汇单元的独立的原子元素。每一个语汇单元能大致与语言中的“单词”对应起来,这个步骤决定文档中的文本域如何分割成语汇单元系列。lucene提供了大量内嵌的分析器可以轻松控制这步操作。
  4. 文档索引: 将文档加入到索引列表中。Lucene在这一步骤中提供了强档的API,只需简单调用提供的几个方法就可以实现出文档索引的建立。为了提供好的用户体验,索引是必须要处理好的一环:在设计和定制索引程序时必须围绕如何提高用户的搜索体验来进行。

四. 搜索组件

  搜索组件即为输入搜索短语,然后进行分词,然从索引中查找单词,从而找到包含该单词的文档。搜索质量由查准率和查全率来衡量。搜索组件主要包括以下内容:

  1. 用户搜索界面:主要是和用户进行交互的页面,也就是呈现在浏览器中能看到的东西,这里主要考虑的就是页面UI设计了。一个良好的UI设计是吸引用户的重要组成部分。
  2. 建立查询:建立查询主要是指用户输入所要查询的短语,以普通HTML表单或者ajax的方式提交到后台服务器端。然后把词语传递给后台搜索引擎。这就是一个简单建立查询的过程。
  3. 搜索查询:即为查询检索索引然后返回与查询词语匹配的文档。然后把返回来的结构按照查询请求来排序。搜索查询组件覆盖了搜索引擎中大部分的复杂内容。
  4. 展现结果:所谓展现结果,和第一个搜索界面类似。都是一个与用户交互的前端展示页面,作为一个搜索引擎,用户体验永远是第一位。其中前端展示在用户体现上占据了重要地位。

五. 官网实例解析

Lucene的使用主要体现在两个步骤:

  1. 创建索引,通过IndexWriter对不同的文件进行索引的创建,并将其保存在索引相关文件存储的位置中。
  2. 通过索引查寻关键字相关文档。

下面针对官网上面给出的一个例子,进行分析:

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);// Store the index in memory:Directory directory = new RAMDirectory();// To store an index on disk, use this instead://Directory directory = FSDirectory.open("/tmp/testindex");IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer);IndexWriter iwriter = new IndexWriter(directory, config);Document doc = new Document();String text = "This is the text to be indexed.";doc.add(new Field("fieldname", text, TextField.TYPE_STORED));iwriter.addDocument(doc);iwriter.close();// Now search the index:DirectoryReader ireader = DirectoryReader.open(directory);IndexSearcher isearcher = new IndexSearcher(ireader);// Parse a simple query that searches for "text":QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "fieldname", analyzer);Query query = parser.parse("text");ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;assertEquals(1, hits.length);// Iterate through the results:for (int i = 0; i < hits.length; i++) {Document hitDoc = isearcher.doc(hits[i].doc);assertEquals("This is the text to be indexed.", hitDoc.get("fieldname"));}ireader.close();directory.close();

索引的创建

  首先,我们需要定义一个词法分析器。

  比如一句话,“我爱我们的中国!”,如何对他拆分,扣掉停顿词“的”,提取关键字“我”“我们”“中国”等等。这就要借助的词法分析器Analyzer来实现。这里面使用的是标准的词法分析器,如果专门针对汉语,还可以搭配paoding,进行使用。

1 Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);

  参数中的Version.LUCENE_CURRENT,代表使用当前的Lucene版本,本文环境中也可以写成Version.LUCENE_40。

  第二步,确定索引文件存储的位置,Lucene提供给我们两种方式:

  1 本地文件存储 

Directory directory = FSDirectory.open("/tmp/testindex");

  2 内存存储

Directory directory = new RAMDirectory();

  可以根据自己的需要进行设定。

  第三步,创建IndexWriter,进行索引文件的写入。

IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer);
IndexWriter iwriter = new IndexWriter(directory, config);

  这里的IndexWriterConfig,据官方文档介绍,是对indexWriter的配置,其中包含了两个参数,第一个是目前的版本,第二个是词法分析器Analyzer。 

  第四步,内容提取,进行索引的存储。

Document doc = new Document();
String text = "This is the text to be indexed.";
doc.add(new Field("fieldname", text, TextField.TYPE_STORED));
iwriter.addDocument(doc);
iwriter.close();

  第一行,申请了一个document对象,这个类似于数据库中的表中的一行。

  第二行,是我们即将索引的字符串。

  第三行,把字符串存储起来(因为设置了TextField.TYPE_STORED,如果不想存储,可以使用其他参数,详情参考官方文档),并存储“表明”为"fieldname".

  第四行,把doc对象加入到索引创建中。

  第五行,关闭IndexWriter,提交创建内容。

  这就是索引创建的过程。

关键字查询:

  第一步,打开存储位置

DirectoryReader ireader = DirectoryReader.open(directory);

  第二步,创建搜索器

IndexSearcher isearcher = new IndexSearcher(ireader);

  第三步,类似SQL,进行关键字查询

复制代码
QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "fieldname", analyzer);
Query query = parser.parse("text");
ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;
assertEquals(1, hits.length);
for (int i = 0; i < hits.length; i++) {Document hitDoc = isearcher.doc(hits[i].doc);assertEquals("This is the text to be indexed.",hitDoc.get("fieldname"));
}
复制代码

  这里,我们创建了一个查询器,并设置其词法分析器,以及查询的“表名“为”fieldname“。查询结果会返回一个集合,类似SQL的ResultSet,我们可以提取其中存储的内容。

  关于各种不同的查询方式,可以参考官方手册,或者推荐的PPT

  第四步,关闭查询器等。

ireader.close();
directory.close();

自己实现的一个小实例:对一个文件夹内的内容进行索引的创建,并根据关键字筛选文件,并读取其中的内容

 

package cn.lnu.edu.yxk;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
/*** 对一个文件夹内的内容进行索引的创建,并根据关键字筛选文件,读取其中的内容。* @author yxk**/
public class IndexManager {private static String content = "";//文件里面的内容private static String INDEX_DIR = "D:\\test\\luceneIndex";//索引创建的存储目录private static String DATA_DIR = "D:\\test\\luceneData";//文件夹的目录private static Analyzer analyzer = null;//词法分析器private static Directory directory = null;//索引文件存储的位置private static IndexWriter indexWriter = null;//创建索引器,索引文件的写入/*** 创建当前文件目录的索引* @param path当前目录的文件* @return 返回是否创建成功*/public static Boolean createIndex(String path) {Date date1 = new Date();//创建需要的时间List<File> files = listFile(path);// 获取指定目录下得所有符合条件的文件// 获取文件的内容for (File file : files) {content = "";//通过文件类型获取文件的内容String type = file.getName().substring(file.getName().lastIndexOf(".") + 1);if ("txt".equalsIgnoreCase(type)) {content += txt2String(file);} else if ("doc".equalsIgnoreCase(type)) {content += doc2String(file);} else if ("xls".equalsIgnoreCase(type)) {content += xls2String(file);}System.out.println("name"+file.getName());System.out.println("path"+file.getPath());//System.out.println(file.getName().getBytes().toString());System.out.println();try {analyzer = new StandardAnalyzer();//词法分析器directory = FSDirectory.open(new File(INDEX_DIR).toPath());//索引创建存储的位置// System.out.println("ssss"// + new File(INDEX_DIR).toPath().toString());//自动创建索引目录File indexFile = new File(INDEX_DIR);if (!indexFile.exists()) {indexFile.mkdirs();}//索引文件的写入IndexWriterConfig config = new IndexWriterConfig(analyzer);indexWriter = new IndexWriter(directory, config);/** 内容提取,进行索引的存储*///申请了一个document对象,这个类似于数据库中的表中的一行。Document document = new Document();//把字符串存储起来(因为设置了TextField.TYPE_STORED,如果不想存储,可以使用其他参数,详情参考官方文档),并存储“表明”为"fieldname".document.add(new org.apache.lucene.document.TextField("filename", file.getName(), Field.Store.YES));//文件名索引创建document.add(new org.apache.lucene.document.TextField("content", content, Field.Store.YES));//文件内容索引创建document.add(new org.apache.lucene.document.TextField("path",file.getPath(), Field.Store.YES));//文件路径索引的创建//把document对象加入到索引创建中indexWriter.addDocument(document);//关闭IndexWriter,提交创建内容。indexWriter.commit();closeWriter();} catch (IOException e) {e.printStackTrace();}content = "";}Date date2 = new Date();System.out.println("创建索引-----耗时:" + (date2.getTime() - date1.getTime())+ "ms\n");return true;}/*** 查询索引,返回符合条件的文件* * @param 查询的字符串* @return 符合条件的结果* @throws IOException*/public static void serarchIndex(String text) {Date date1 = new Date();try {//打开存储位置directory = FSDirectory.open(new File(INDEX_DIR).toPath());analyzer = new StandardAnalyzer();DirectoryReader ireader = DirectoryReader.open(directory);//创建搜索器IndexSearcher isearcher = new IndexSearcher(ireader);/** 类似SQL,进行关键字查询*/QueryParser parser = new QueryParser("content", analyzer);Query query = parser.parse(text);//创建了一个查询器,并设置其词法分析器,以及查询的“表名“为”fieldname“。查询结果会返回一个集合,类似SQL的ResultSet,我们可以提取其中存储的内容。ScoreDoc[] hits = isearcher.search(query, 1000).scoreDocs;for (int i = 0; i < hits.length; i++) {Document hitDoc = isearcher.doc(hits[i].doc);System.out.println("-----------");System.out.println(hitDoc.get("filename"));System.out.println(hitDoc.get("content"));System.out.println(hitDoc.get("path"));System.out.println("------------");}//关闭查询器ireader.close();directory.close();} catch (IOException e) {e.printStackTrace();} catch (ParseException e) {e.printStackTrace();}Date date2 = new Date();System.out.println("关键字查询-----耗时:" + (date2.getTime() - date1.getTime())+ "ms\n");}/*** * @throws IOException*/private static void closeWriter() throws IOException {if (indexWriter != null)indexWriter.close();}/*** 读取xls文件内容,引入jxl.jar类型的包* @param file* @return 返回内容*/private static String xls2String(File file) {String result = "";try {FileInputStream fis = new FileInputStream(file);StringBuilder sb = new StringBuilder();jxl.Workbook rwb = Workbook.getWorkbook(fis);Sheet[] sheet = rwb.getSheets();for (int i = 0; i < sheet.length; i++) {Sheet rs = rwb.getSheet(i);for (int j = 0; i < rs.getRows(); j++) {Cell[] cells = rs.getRow(j);for (int k = 0; k < cells.length; k++) {sb.append(cells[k].getContents());}}}fis.close();result += sb.toString();} catch (FileNotFoundException e) {e.printStackTrace();} catch (BiffException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return result;}/*** 读取doc类型文件的内容,通过poi.jar* @param file的类型* @return 返回文件的内容*/private static String doc2String(File file) {String result = "";try {FileInputStream fis = new FileInputStream(file);//文件输入流HWPFDocument document = new HWPFDocument(fis);Range range = document.getRange();result += range.text();fis.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return result;}/*** 读取txt文件的内容* * @param file想要读取的文件类型* @return 返回文件内容*/private static String txt2String(File file) {String result = "";try {BufferedReader reader = new BufferedReader(new FileReader(file));String s = "";while ((s = reader.readLine()) != null) {result += result + "\n" + s;}reader.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return result;}/*** 过滤当前目录下得文件* @param path 当前目录下得文件* @return 返回符合条件的文件*/private static List<File> listFile(String path) {File[] files = new File(path).listFiles();List<File> fileList = new ArrayList<File>();for (File file : files) {if (isTxtFile(file.getName())) {fileList.add(file);}}return fileList;}/*** 判断是否为目标文件,支持的格式为.txt,.doc,.xls文件格式 如果是文件类型满足过滤条件,返回true;否则返回false* @param name 根据文件名的后缀* @return 是否符合格式规范*/private static boolean isTxtFile(String name) {if (name.lastIndexOf(".txt") > 0)return true;else if (name.lastIndexOf(".doc") > 0)return true;else if (name.lastIndexOf(".xls") > 0)return true;return false;}public static void main(String[] args) {//创建索引目录,运行一次,重新创建一次File fileIndex = new File(INDEX_DIR);if (deleteIndex(fileIndex)) {fileIndex.mkdir();} else {fileIndex.mkdir();}//创建索引文件createIndex(DATA_DIR);//通过关键字查询serarchIndex("中华");}/*** 删除文件目录下得所有文件* * @param fileIndex 当前索引目录下得文件* @return 返回是否删除重新创建*/private static boolean deleteIndex(File fileIndex) {if (fileIndex.isDirectory()) {File[] files = fileIndex.listFiles();for (int i = 0; i < files.length; i++) {deleteIndex(files[i]);}}fileIndex.delete();return true;}}
通过对几位博文的分析进行总结;

原文博客出自:http://blog.csdn.net/csh624366188/article/category/895342

和https://www.cnblogs.com/xing901022/p/3933675.html


---------------------
作者:jofjhh
来源:CSDN
原文:https://blog.csdn.net/m0_37913549/article/details/78989078
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284355.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET 6.0中使用Identity框架实现JWT身份认证与授权

原文作者&#xff1a;Sarathlal Saseendran原文链接&#xff1a;https://www.c-sharpcorner.com/article/jwt-authentication-and-authorization-in-net-6-0-with-identity-framework/翻译&#xff1a;沙漠尽头的狼&#xff08;谷歌翻译加持&#xff09;介绍微软于 2021 年 11 …

adb devices 里面有很多 emulator-XXXX的解决方法

2019独角兽企业重金招聘Python工程师标准>>> adb kill-server 转载于:https://my.oschina.net/sfshine/blog/700354

MQ(Message Queue)简介

一、何为MQ&#xff1f; MQ全称为Message Queue, 消息队列&#xff08;MQ&#xff09;是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息&#xff08;针对应用程序的数据&#xff09;来通信&#xff0c;而无需专用连接来链接它们。消息传递指的是程序之间通…

Blazor University (39)JavaScript 互操作 —— 更新 document title

原文链接&#xff1a;https://blazor-university.com/javascript-interop/calling-javascript-from-dotnet/updating-the-document-title/更新 document title源代码[1]在创建 Blazor 布局[2]部分中&#xff0c;我们看到了 Blazor 应用程序如何存在于 HTML&#xff08;或 cshtm…

IIS 日志文件位置

IIS 6 Log files location IIS 6中日志文件的位置%windir%\System32\LogFilesIIS 7 Log files location IIS的日志文件的位置%SystemDrive%\inetpub\logs\LogFiles用户每打开一次网页&#xff0c;iis 都会记录用户IP、访问的网页地址、访问时间、访问状态等信息&#xff0c;这些…

APP测试流程和测试点

1 APP测试基本流程 1.1流程图 1.2测试周期 测试周期可按项目的开发周期来确定测试时间&#xff0c;一般测试时间为两三周&#xff08;即15个工作日&#xff09;&#xff0c;根据项目情况以及版本质量可适当缩短或延长测试时间。正式测试前先向主管确认项目排期。 1.3测试资源 测…

39所强基计划试点高校已全部公布招生简章

截至目前(4月8日下午) 39所强基计划试点高校 已全部公布招生简章 各高校招生要求是什么&#xff1f; 招生专业有哪些&#xff1f; 什么时候报名&#xff1f; 一起来看 北京大学 招生对象及报名条件 各省&#xff08;区、市&#xff09;符合2022年全国普通高等学校招生统…

【ArcGIS错误异常100问】之001:License服务无法启动权威解决办法

测试环境&#xff1a; 操作系统&#xff1a;Windows10ArcGIS版本&#xff1a;10.X结果&#xff1a;通过测试 文章目录1. 错误提示2. 问题分析3. 解决办法3.1 关闭Windows Defender3.2 关闭系统防火墙3.3 删除迈克菲&#xff08;McAfee&#xff09;杀毒软件3.4 在系统服务中启动…

ASP.NET Core 技术内幕与项目实战读后感

前几天拿到了杨中科老师的新书《ASP.NET Core 技术内幕与项目实战》&#xff0c;迫不及待的“两”口气读完了。用一句话来总结&#xff0c;这是一本写给.NET开发者的非常实用的接地气的好书&#xff0c;感觉有必要自发为这本书宣传一波。杨老师在 .NET 开发者社区中的知名度非常…

avalon2学习教程15指令总结

avalon的指令在上一节已经全部介绍完毕&#xff0c;当然有的语焉不详&#xff0c;如ms-js。本节主要总结我对这方面的思考与探索。 MVVM的成功很大一语分是来自于其指令&#xff0c;或叫绑定。让操作视图的功能交由形形式式的指令来代劳。VM&#xff0c;成了一个大管家。它只一…

【ArcGIS错误异常100问】之002:Error 000735 简化容差:值是必需的(简化线、简化面工具)

测试环境&#xff1a; 操作系统&#xff1a;windows7ArcGIS版本&#xff1a;10.2结果&#xff1a;通过测试 文章目录1. 错误提示2. 问题分析3. 解决办法4. 问题验证1. 错误提示 在ArcGIS中使用简化面或者简化线工具时&#xff0c;点击确定会提示Error 000735&#xff1a;简化容…

.NET桌面开发的一些思考

在22日&#xff0c;我在公众号上发布了一条短文字&#xff0c;内容如下&#xff1a;其实在.NET开发大军中&#xff0c;还有一股力量&#xff0c;那就是桌面程序的开发者们。他们很少发声&#xff0c;可能技术成熟&#xff0c;可能太企业化了&#xff0c;也可能我没关注到。最近…

【ArcGIS错误异常100问】之003:属性表中文乱码解决办法总结

测试环境&#xff1a; 操作系统&#xff1a;windows7ArcGIS版本&#xff1a;10.X、Pro结果&#xff1a;通过测试 文章目录1. 错误提示2. 原因分析3. 解决方法4. 问题验证1. 错误提示 如图所示&#xff0c;安装完ArcGIS Pro后&#xff0c;由于计算机系统和应用软件字符编码的问…

大型网站架构演化(二)——应用服务和数据服务分离

随着网站业务的发展&#xff0c;一台服务器逐渐不能满足需求&#xff1a;越来越多的用户访问导致性能越来越差&#xff0c;越来越多的数据导致存储空间不足。这时就需要将应用和数据分离。应用和数据分离后整个网站使用三台服务器&#xff1a;应用服务器、文件服务器和数据库服…

再不自动化就晚啦!优云教你4步打造基于CentOS的产品镜像

随着Linux程序的增多&#xff0c;软件的安装过程中经常出现如下问题&#xff1a; 1、硬件配置类似或者相同时&#xff0c;批量安装系统和软件&#xff0c;希望实现自动化安装&#xff0c;减少安装时间和人为出错。 2、工程实施人员在不同客户现场进行系统和软件安装(硬件配置不…

【ArcGIS错误异常100问】之004:ArcGIS表转Excel超了65535限制解决办法

测试环境&#xff1a; 操作系统&#xff1a;windows7ArcGIS版本&#xff1a;10.2 文章目录1. 错误提示2. 原因分析3. 解决方法1. 错误提示 如下图&#xff0c;当矢量shp图斑数目过多&#xff0c;文件超过了65535条记录时&#xff0c;利用ArcGIS的表转Excel工具处理成Excel文件…

[转]硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战

在Redis 缓存击穿&#xff08;失效&#xff09;、缓存穿透、缓存雪崩怎么解决&#xff1f;中我们说到可以使用布隆过滤器避免「缓存穿透」。 码哥&#xff0c;布隆过滤器还能在哪些场景使用呀&#xff1f; 比如我们使用「码哥跳动」开发的「明日头条」APP 看新闻&#xff0c;如…

Senparc.Weixin.Sample.MP源码剖析

Senparc.Weixin.Sample.MP是微信公众号样例的.NET6源码&#xff0c;项目配置文件appsettings.json的修改和微信公众号测试环境的搭建参考&#xff1a;微信公众号调试与Natapp环境搭建。接下来从项目结构&#xff0c;项目应用和项目源码3个角度来进行讲解。一.项目结构角度项目代…

mock.js使用

一、Mock.js入门 1&#xff0e; 什么是mock.js? Mock.js &#xff08;官网http://mockjs.com/&#xff09;是一款模拟数据生成器&#xff0c;旨在帮助前端攻城狮独立 于后端进行开发&#xff0c;帮助编写单元测试。提供了以下模拟功能&#xff1a; 1,根据数据模板生成模拟数据…

【ArcGIS微课1000例】0042:ArcGIS自带取色器工具的妙用

在ArcGIS中作图时,通常要进行颜色对照填充,输入特定的RGB值,本文介绍ArcGIS自带取色器工具的妙用,及第三方颜色拾取工具。 文章目录 一、ArcGIS自带取色器二、第三方取色器工具一、ArcGIS自带取色器 很多人可能不知道,ArcGIS中自带取色器工具,如下图所示。 当然了,自带…