- 浏览: 8434 次
- 性别:
- 来自: 北京
文章分类
最新评论
转载:http://blog.csdn.net/zyb243380456/article/details/7217434
<1>.SolrDispatchFilter实例化做的事情 过滤solr相关请求 找到solrHome [SolrDispatchFilter->SolrResourceLoader->Config] <2>.SolrDispatchFilter初始化做的事情 帮助初始化CoreContianer的一个内部类 [CoreContainer.Initializer----------->CoreContainer->CoreAdminHandler->CoreContainer->] 将solrCore容器初始化并且将所有的SolrCore实例装载到CoreContainer中 <3>.SolrDispatchFilter过滤的时候做的事情 [在solrDispatchFilter中解决所有全文检索的问题包括对索引库的读写等对索引库的性能调优以及控制] 1.SolrDispatchFilter.java /** 这个类是一个标准的过滤器检查所有的请求路径将他们映射到在solrconfig.xml *中定义的处理器上,从过滤器的声明周期来看他有被容器实例化,初始化, *过滤,以及最终的destroy被容器给销毁 *solr是在什么时候加载到我们的web容器中去的就是从这个过滤器的诞生开始的所以 *我们的焦点就在这个过滤器上 */ protected CoreContainer cores;/** 用来保存多个索引库实例的一个多实例solr容器 */ protected String pathPrefix = null;/** 定义以什么开头的请求访问路径将会被这个过滤器过滤这个路径相对与虚拟的上下文路径来说的也就是不包括 http://localhost:8080/myapp/ [...]这么一段路径 */ protected String abortErrorMessage = null; protected String solrConfigFilename = null; protected final Map<SolrConfig, SolrRequestParsers> parsers = new WeakHashMap<SolrConfig, SolrRequestParsers>();/** 请求分析器的一个集合*/ protected final SolrRequestParsers adminRequestParser;/** solr请求分析器专门用于管理solr请求地址的分析 */ /** 这个构造函数覆盖了默认的构造函数所以容器会调用他 */ public SolrDispatchFilter() { try { adminRequestParser = new SolrRequestParsers( /** 请求分析管理对象管理所有的的请求分析器并且拥有请求分析器的集合对象*/ new Config( null,"solr",new InputSource( new ByteArrayInputStream("<root/>".getBytes("UTF-8"))),"") ); } catch (Exception e) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,e); } } /** 这是过滤器的初始化方法他会从web.xml中解析自己的配置信息 *在容器调用该过滤器实例的init方法的时候实例化了几个中要的对象一个是CoreContainer.Initializer这个内部类 *然后这个内部类接着又将CoreContainer给实例化了这个CoreContainer实例化的时候需要的配置文件是solr.xml也就是solrHome的父目下的一个配置文件 *通过这个配置文件的配置可以告诉我们的CoreContainer容器他会容纳多少个索引库实例然后怎么去管理这些实例 *他是通过xPath的方式将配置文件以FileInputStream的形式读取上来然后根据不同的命名空间来进行获取对应的配置信息 * try { * SolrResourceLoader loader = new SolrResourceLoader(null); * InputStream cfgis = new FileInputStream(new File("F:/solr/solr.xml")); * Config cfg = new Config(loader, null, cfgis, null);/** 所对应配置文件解析方式以及构造方式这个对象对应所有的配置文件的解析内部采用xpath的方式进行一个解析 */ * String s = cfg.get("solr/cores/@adminPath"); * /** 得到 @adminPath 这个属性的文本内容 * <solr persistent="false"> * <cores adminPath="/admin/cores" defaultCoreName="collection1"> * <core name="collection1" instanceDir="." /> * </cores> * </solr> */ * * System.out.println(s); * } catch (Exception e) { * e.printStackTrace(); * } *关键还是根据solr.xml这个文件可以是是默认的也可以是自己配置的实例化了CoreContainer这个容器 */ /** 实例化CoreContainer容器将所有的solrCore实例装到容器中 */ public void init(FilterConfig config) throws ServletException { log.info("SolrDispatchFilter.init()"); boolean abortOnConfigurationError = true; CoreContainer.Initializer init = createInitializer();/** 初始化CoreContianer的内部类 */ try { /** 配置当前web应用上下文参数*/ this.pathPrefix = config.getInitParameter( "path-prefix" );/** 可以在过滤器配置文件中指定好只针对该特殊的请求进行一个过滤*/ init.setSolrConfigFilename(config.getInitParameter("solrconfig-filename"));/** 指定好solr配置文件的名字是什么 */ this.cores = init.initialize();/** 正式将CoreContainer进行一个初始化并创建实例对象然后将所有的solrCore实例放到容器中 */ abortOnConfigurationError = init.isAbortOnConfigurationError(); log.info("user.dir=" + System.getProperty("user.dir")); } catch( Throwable t ) { /** 捕获这个异常我们的过滤器将会继续工作 */ log.error( "Could not start Solr. Check solr/home property", t); SolrConfig.severeErrors.add( t ); SolrCore.log( t ); } /** 如果服务器报错可以选择性的忽略该错误 */ if( abortOnConfigurationError && SolrConfig.severeErrors.size() > 0 ) { StringWriter sw = new StringWriter(); PrintWriter out = new PrintWriter( sw ); out.println( "Severe errors in solr configuration.\n" ); out.println( "Check your log files for more detailed information on what may be wrong.\n" ); out.println( "If you want solr to continue after configuration errors, change: \n"); out.println( " <abortOnConfigurationError>false</abortOnConfigurationError>\n" ); out.println( "in "+init.getSolrConfigFilename()+"\n" ); for( Throwable t : SolrConfig.severeErrors ) { out.println( "-------------------------------------------------------------" ); t.printStackTrace( out ); } out.flush(); // Servlet containers behave slightly differently if you throw an exception during // initialization. Resin will display that error for every page, jetty prints it in // the logs, but continues normally. (We will see a 404 rather then the real error) // rather then leave the behavior undefined, lets cache the error and spit it out // for every request. abortErrorMessage = sw.toString(); //throw new ServletException( abortErrorMessage ); } log.info("SolrDispatchFilter.init() done"); } /** Method to override to change how CoreContainer initialization is performed. */ protected CoreContainer.Initializer createInitializer() { return new CoreContainer.Initializer(); } /** 在销毁这个过滤器的时候同时将释放所有的索引实例的文件流 */ public void destroy() { if (cores != null) { cores.shutdown(); cores = null; } } /** 将对特定的需要全文检索的请求进行一个过滤然后提供全文检索服务 */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if( abortErrorMessage != null ) { ((HttpServletResponse)response).sendError( 500, abortErrorMessage ); return; } if( request instanceof HttpServletRequest) { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse resp = (HttpServletResponse)response; SolrRequestHandler handler = null;/** 请求处理器*/ SolrQueryRequest solrReq = null; /** 查询请求*/ SolrCore core = null; /** 请求资源所对应的solrCore实例*/ String corename = ""; /** solrCore实例的名字*/ try { /** 将我们的CoreContainer容器保存到请求中 */ req.setAttribute("org.apache.solr.CoreContainer", cores); String path = req.getServletPath();/**http://localhost:8080/collection2/admin/这样一段URL那么path为"collection2/admin/" */ if( req.getPathInfo() != null ) { // this lets you handle /update/commit when /update is a servlet path += req.getPathInfo(); } /** 如果路径是http://localhost:8080/mysolr/test/select/... 为了能够让solr知道这个请求URL有检索需要首先要把这个test/这段字符窜给截取*/ if( pathPrefix != null && path.startsWith( pathPrefix ) ) { path = path.substring( pathPrefix.length() ); } /** 得到管理CoreContainer这个容器的路径的名字*/ String alternate = cores.getManagementPath(); if (alternate != null && path.startsWith(alternate)) { path = path.substring(0, alternate.length()); } // unused feature ? int idx = path.indexOf( ':' ); if( idx > 0 ) { // save the portion after the ':' for a 'handler' path parameter path = path.substring( 0, idx ); } /** 检查是否需要去管理页面 */ if( path.equals( cores.getAdminPath() ) ) { handler = cores.getMultiCoreHandler(); solrReq = adminRequestParser.parse(null,path, req); handleAdminRequest(req, response, handler, solrReq); return; } else { /** 另外,我们应该从路径中找到solrCore的名字*/ idx = path.indexOf( "/", 1 ); if( idx > 1 ) { /** 通过请求参数得到solrCore实例的名字*/ corename = path.substring( 1, idx ); core = cores.getCore(corename); if (core != null) { path = path.substring( idx );/** 将路径中的solrCore名字截取掉 */ } } if (core == null) { corename = ""; core = cores.getCore(""); } } /** 使用一个有效的solrcore实例*/ if( core != null ) { final SolrConfig config = core.getSolrConfig(); /** 从solrCore的实例缓存中得到一个请求解析对象或者创建一个新的缓存起来*/ SolrRequestParsers parser = null; parser = parsers.get(config); if( parser == null ) { parser = new SolrRequestParsers(config); parsers.put(config, parser );/** 将加载这个solrCore实例所配置的所有请求解析器对象*/ } /** 如果没有设置请求处理器的类型从请求路径得到处理器*/ /** 我们已经选择了一个请求处理器*/ if( handler == null && path.length() > 1 ) { /**没有匹配空窜或者/是有效字符 */ handler = core.getRequestHandler( path ); /** 没有处理器但是允许处理查询*/ if( handler == null && parser.isHandleSelect() ) { if( "/select".equals( path ) || "/select/".equals( path ) ) {/**是一个查询请求 */ solrReq = parser.parse( core, path, req );/** 得到请求查询对象 */ String qt = solrReq.getParams().get( CommonParams.QT );/** 得到查询类型也就是对应的查询请求处理器的名字 */ handler = core.getRequestHandler( qt );/** 根据查询类型得到请求查询处理器对象 */ if( handler == null ) { throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+qt);/**如果发生异常表示没有对应的请求查询处理器 */ } } } } // With a valid handler and a valid core... /** 使用一个有效的处理器和有效的solrCore实例*/ if( handler != null ) { // if not a /select, create the request if( solrReq == null ) { solrReq = parser.parse( core, path, req ); } final Method reqMethod = Method.getMethod(req.getMethod());/** 得到http请求提交的方式*/ HttpCacheHeaderUtil.setCacheControlHeader(config, resp, reqMethod); // unless we have been explicitly told not to, do cache validation // if we fail cache validation, execute the query if (config.getHttpCachingConfig().isNever304() || !HttpCacheHeaderUtil.doCacheHeaderValidation(solrReq, req, reqMethod, resp)) { SolrQueryResponse solrRsp = new SolrQueryResponse(); /* even for HEAD requests, we need to execute the handler to * ensure we don't get an error (and to make sure the correct * QueryResponseWriter is selected and we get the correct * Content-Type) */ /** solr所有的操作的最后一步*/ this.execute( req, handler, solrReq, solrRsp );/** 根据请求对象,根据请求参数中指定的处理器名字得到的处理器,根据响应对象,以及发送请求的方式对索引库进行一个读写操作 */ HttpCacheHeaderUtil.checkHttpCachingVeto(solrRsp, resp, reqMethod); // add info to http headers //TODO: See SOLR-232 and SOLR-267. /*try { NamedList solrRspHeader = solrRsp.getResponseHeader(); for (int i=0; i<solrRspHeader.size(); i++) { ((javax.servlet.http.HttpServletResponse) response).addHeader(("Solr-" + solrRspHeader.getName(i)), String.valueOf(solrRspHeader.getVal(i))); } } catch (ClassCastException cce) { log.log(Level.WARNING, "exception adding response header log information", cce); }*/ QueryResponseWriter responseWriter = core.getQueryResponseWriter(solrReq);/** 将请求结果通过输出流写出到客户端*/ writeResponse(solrRsp, response, responseWriter, solrReq, reqMethod); } return; // we are done with a valid handler } // otherwise (we have a core), let's ensure the core is in the SolrCore request attribute so // a servlet/jsp can retrieve it else { req.setAttribute("org.apache.solr.SolrCore", core); // Modify the request so each core gets its own /admin /** 修改请求根据不同的solrcore的管理界面进行一个转发*/ if( path.startsWith( "/admin" ) ) { req.getRequestDispatcher( pathPrefix == null ? path : pathPrefix + path ).forward( request, response ); return; } } } log.debug("no handler or core retrieved for " + path + ", follow through..."); } catch (Throwable ex) { sendError( (HttpServletResponse)response, ex ); return; } finally { if( solrReq != null ) { solrReq.close(); } if (core != null) { core.close(); } } } /** 让web应用处理其他请求*/ chain.doFilter(request, response); } 2.Config.java /** 对应到所有solr的关键配置文件以及对配置文件的一个加载 在这个方法中初始话了一个重要的类为SolrResourceLoader以及Config本生 */ public Config(SolrResourceLoader loader, String name, InputSource is, String prefix) throws ParserConfigurationException, IOException, SAXException { if( loader == null ) { loader = new SolrResourceLoader( null );/** 这里到了SolrResourceLoader的构造方法之后又进行了一个相应的定位然后定位到了SolrHome也就是索引库和重要的配置文件所在目录 */ } this.loader = loader; this.name = name; this.prefix = (prefix != null && !prefix.endsWith("/"))? prefix + '/' : prefix; try { javax.xml.parsers.DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); if (is == null) { is = new InputSource(loader.openConfig(name)); is.setSystemId(SystemIdResolver.createSystemIdFromResourceName(name)); } // only enable xinclude, if a SystemId is available if (is.getSystemId() != null) { try { dbf.setXIncludeAware(true); dbf.setNamespaceAware(true); } catch(UnsupportedOperationException e) { log.warn(name + " XML parser doesn't support XInclude option"); } } final DocumentBuilder db = dbf.newDocumentBuilder(); db.setEntityResolver(new SystemIdResolver(loader)); db.setErrorHandler(xmllog); try { doc = db.parse(is); } finally { // some XML parsers are broken and don't close the byte stream (but they should according to spec) IOUtils.closeQuietly(is.getByteStream()); } DOMUtil.substituteProperties(doc, loader.getCoreProperties()); } catch (ParserConfigurationException e) { SolrException.log(log, "Exception during parsing file: " + name, e); throw e; } catch (SAXException e) { SolrException.log(log, "Exception during parsing file: " + name, e); throw e; } catch( SolrException e ){ SolrException.log(log,"Error in "+name,e); throw e; } } 3.SolrResourceLoader.java public SolrResourceLoader( String instanceDir, ClassLoader parent, Properties coreProperties ) { if( instanceDir == null ) { this.instanceDir = SolrResourceLoader.locateSolrHome();/**这个方法用于定位到solrHome的主目录 */ } else{ this.instanceDir = normalizeDir(instanceDir); } log.info("Solr home set to '" + this.instanceDir + "'"); this.classLoader = createClassLoader(null, parent); addToClassLoader("./lib/", null); this.coreProperties = coreProperties; } /** * Determines the solrhome from the environment. * 决定从整个虚拟机环境中找到solrhome * Tries JNDI (java:comp/env/solr/home) then system property (solr.solr.home); * 尝试使用JNDI或系统虚拟机系统属性进行找到solrhome所对应的地址 * if both fail, defaults to solr/ * 如果两者都失败,默认在当前目录进行进行一个寻找 * @return the instance directory name * 返回实例所在目录的名字 */ /** * Finds the solrhome based on looking up the value in one of three places: * 基于三个地方查找solrhome * <ol> * <li>JNDI: via java:comp/env/solr/home</li> * <li>JNDI: 同过jndi上下文中进行一个查找</li> * <li>The system property solr.solr.home</li> * <li>系统的属性solr.solr.home</li> * <li>Look in the current working directory for a solr/ directory</li> * <li>在当前工作目录中进行一个查找根据solr/</li> * </ol> * * The return value is normalized. Normalization essentially means it ends in a trailing slash. * 返回一个标准化的值. * @return A normalized solrhome * @see #normalizeDir(String) */ public static String locateSolrHome() { String home = null; // Try JNDI try { Context c = new InitialContext(); home = (String)c.lookup("java:comp/env/"+project+"/home"); log.info("Using JNDI solr.home: "+home ); } catch (NoInitialContextException e) { log.info("JNDI not configured for "+project+" (NoInitialContextEx)"); } catch (NamingException e) { log.info("No /"+project+"/home in JNDI"); } catch( RuntimeException ex ) { log.warn("Odd RuntimeException while testing for JNDI: " + ex.getMessage()); } // Now try system property if( home == null ) { String prop = project + ".solr.home"; home = System.getProperty(prop); if( home != null ) { log.info("using system property "+prop+": " + home ); } } // if all else fails, try if( home == null ) { home = project + '/'; log.info(project + " home defaulted to '" + home + "' (could not find system property or JNDI)"); } return normalizeDir( home ); } 4.SolrRequestParsers.java 这个类用于初始化所有的请求管理器以及将这些请求管理器放到一个集合中保存起来 public SolrRequestParsers( Config globalConfig ) { long uploadLimitKB = 1048; if( globalConfig == null ) { uploadLimitKB = Long.MAX_VALUE; enableRemoteStreams = true; handleSelect = true; } else { uploadLimitKB = globalConfig.getInt( "requestDispatcher/requestParsers/@multipartUploadLimitInKB", (int)uploadLimitKB ); enableRemoteStreams = globalConfig.getBool( "requestDispatcher/requestParsers/@enableRemoteStreaming", false ); // Let this filter take care of /select?xxx format handleSelect = globalConfig.getBool( "requestDispatcher/@handleSelect", handleSelect ); } MultipartRequestParser multi = new MultipartRequestParser( uploadLimitKB ); RawRequestParser raw = new RawRequestParser(); standard = new StandardRequestParser( multi, raw ); // I don't see a need to have this publicly configured just yet // adding it is trivial parsers = new HashMap<String, SolrRequestParser>(); parsers.put( MULTIPART, multi ); parsers.put( RAW, raw ); parsers.put( SIMPLE, new SimpleRequestParser() ); parsers.put( STANDARD, standard ); parsers.put( "", standard ); } 5.CoreCainter.java /** 初始化容器的时候就加载索引库的代码 */ /** * 加载solr.xml列出所有可以使用的solrCore配置信息 * * @param dir 所有资源文件所在的主目录 * @param cfgis solr.xml文件的输入字节流 * @throws ParserConfigurationException 解析solr.xml文件的时候抛出的异常 * @throws IOException 文件读写操作时候抛出的异常 * @throws SAXException sax解析抛出的异常 */ public void load(String dir, InputSource cfgis) throws ParserConfigurationException, IOException, SAXException { this.loader = new SolrResourceLoader(dir); solrHome = loader.getInstanceDir();/** 找到所有资源文件所在的主目录*/ Config cfg = new Config(loader, null, cfgis, null);/** 根据cfgis这个输入字节流构造config对象*/ String dcoreName = cfg.get("solr/cores/@defaultCoreName", null);/** 根据xpath的方式对该solr.xml文件进行解析*/ if(dcoreName != null) { defaultCoreName = dcoreName; } persistent = cfg.getBool( "solr/@persistent", false ); libDir = cfg.get( "solr/@sharedLib", null); adminPath = cfg.get( "solr/cores/@adminPath", null ); shareSchema = cfg.getBool("solr/cores/@shareSchema", false ); if(shareSchema){ indexSchemaCache = new ConcurrentHashMap<String ,IndexSchema>(); } adminHandler = cfg.get("solr/cores/@adminHandler", null ); managementPath = cfg.get("solr/cores/@managementPath", null ); if (libDir != null) { File f = FileUtils.resolvePath(new File(dir), libDir); log.info( "loading shared library: "+f.getAbsolutePath() ); libLoader = SolrResourceLoader.createClassLoader(f, null); } if (adminPath != null) { if (adminHandler == null) { coreAdminHandler = new CoreAdminHandler(this);/** 生成对CoreCotanier这个容器进行管理的处理器*/ } else { coreAdminHandler = this.createMultiCoreHandler(adminHandler); } } try { containerProperties = readProperties(cfg, ((NodeList) cfg.evaluate("solr", XPathConstants.NODESET)).item(0)); } catch (Throwable e) { SolrConfig.severeErrors.add(e); SolrException.logOnce(log,null,e); } /** 在遍历每一个solrCore之前,检查一下名字是否符合要求 */ /** 使用多个solrCore实例的时候快速找到使用同样名字的solrCore */ { /** 本地的作用域, 不要使用相同的变量名字 */ NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core/@name", /** 找到所有的solrCore的名字列表*/ XPathConstants.NODESET); Set<String> names = new HashSet<String>();/**使用hashSet可以避免出现相同的名字 */ for (int i=0; i<nodes.getLength(); i++) {/** 循环取出SolrCore的名字*/ String name = DOMUtil.getText(nodes.item(i)); if (names.contains(name)) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Multiple cores found with same name: " + name); } names.add(name);/**添加到set集合中 */ } } /** 可选参数配置项{solr.core.schemaName=schema.xml, solr.core.configName=solrconfig.xml, solr.core.instanceDir=.\, solr.core.dataDir=F:\\solr\.\data\, solr.core.name=}*/ /** 正式遍历每一个solrCore的节点配置信息 */ /** 找到所有的core节点like this:【<core name="collection1" instanceDir="." />】*/ NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core", XPathConstants.NODESET); for (int i=0; i<nodes.getLength(); i++) { Node node = nodes.item(i); try { String name = DOMUtil.getAttr(node, "name", null);/**得到solrCore的实例名字 */ if (null == name) {/**如果该core实例子的名字为空将抛出异常 */ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Each core in solr.xml must have a 'name'"); } if (name.equals(defaultCoreName)){/**名字等于默认的solrCore的配置名 */ /** 那么我们将默认的solrCore名字修改为一个空的窜*/ name=""; } /** CoreDescriptor详细的描述了一个SolrCore所拥有的完整配置信息和创建该实例的所有参数 */ CoreDescriptor p = new CoreDescriptor(this, name, DOMUtil.getAttr(node, "instanceDir", null)); /** 处理可选配置项目 */ String opt = DOMUtil.getAttr(node, "config", null); if(solrConfigFilenameOverride != null && name.equals("")) { p.setConfigName(solrConfigFilenameOverride); } else if (opt != null) { p.setConfigName(opt); } opt = DOMUtil.getAttr(node, "schema", null); if (opt != null) { p.setSchemaName(opt); } opt = DOMUtil.getAttr(node, "properties", null); if (opt != null) { p.setPropertiesName(opt); } opt = DOMUtil.getAttr(node, CoreAdminParams.DATA_DIR, null); if (opt != null) { p.setDataDir(opt); } p.setCoreProperties(readProperties(cfg, node)); SolrCore core = create(p); register(name, core, false); } catch (Throwable ex) { SolrConfig.severeErrors.add( ex ); SolrException.logOnce(log,null,ex); } } } 6.SolrConfig.java /** *SolrConfig.java 对应solrConfig.xml *SolrIndexConfig.java 对应索引文件的时候的配置 *IndexSchema.java 对应索引字段配置文件对象 *Config schemaConf = new Config(loader, "schema", is, "/schema/");/** 用于解析所有的xml配置文件 */ *Config schemaConf = new Config(loader, "schema", is, "/schema/"); *Document document = schemaConf.getDocument(); *final XPath xpath = schemaConf.getXPath(); *SolrQueryAnalyzer对应到lucene的queryParser *dataDir指定的是索引库存放的地方 */ SolrConfig(SolrResourceLoader loader, String name, InputSource is) throws ParserConfigurationException, IOException, SAXException { super(loader, name, is, "/config/"); initLibs(); luceneMatchVersion = getLuceneVersion("luceneMatchVersion", Version.LUCENE_24); defaultIndexConfig = new SolrIndexConfig(this, null, null); mainIndexConfig = new SolrIndexConfig(this, "mainIndex", defaultIndexConfig); reopenReaders = getBool("mainIndex/reopenReaders", true); booleanQueryMaxClauseCount = getInt("query/maxBooleanClauses", BooleanQuery.getMaxClauseCount()); log.info("Using Lucene MatchVersion: " + luceneMatchVersion); filtOptEnabled = getBool("query/boolTofilterOptimizer/@enabled", false); filtOptCacheSize = getInt("query/boolTofilterOptimizer/@cacheSize",32); filtOptThreshold = getFloat("query/boolTofilterOptimizer/@threshold",.05f); useFilterForSortedQuery = getBool("query/useFilterForSortedQuery", false); queryResultWindowSize = Math.max(1, getInt("query/queryResultWindowSize", 1)); queryResultMaxDocsCached = getInt("query/queryResultMaxDocsCached", Integer.MAX_VALUE); enableLazyFieldLoading = getBool("query/enableLazyFieldLoading", false); filterCacheConfig = CacheConfig.getConfig(this, "query/filterCache"); queryResultCacheConfig = CacheConfig.getConfig(this, "query/queryResultCache"); documentCacheConfig = CacheConfig.getConfig(this, "query/documentCache"); CacheConfig conf = CacheConfig.getConfig(this, "query/fieldValueCache"); if (conf == null) { Map<String,String> args = new HashMap<String,String>(); args.put("name","fieldValueCache"); args.put("size","10000"); args.put("initialSize","10"); args.put("showItems","-1"); conf = new CacheConfig(FastLRUCache.class, args, null); } fieldValueCacheConfig = conf; unlockOnStartup = getBool("mainIndex/unlockOnStartup", false); useColdSearcher = getBool("query/useColdSearcher",false); dataDir = get("dataDir", null); if (dataDir != null && dataDir.length()==0) dataDir=null; userCacheConfigs = CacheConfig.getMultipleConfigs(this, "query/cache"); org.apache.solr.search.SolrIndexSearcher.initRegenerators(this); hashSetInverseLoadFactor = 1.0f / getFloat("//HashDocSet/@loadFactor",0.75f); hashDocSetMaxSize= getInt("//HashDocSet/@maxSize",3000); pingQueryParams = readPingQueryParams(this); httpCachingConfig = new HttpCachingConfig(this); Node jmx = getNode("jmx", false); if (jmx != null) { jmxConfig = new JmxConfiguration(true, get("jmx/@agentId", null), get( "jmx/@serviceUrl", null)); } else { jmxConfig = new JmxConfiguration(false, null, null); } maxWarmingSearchers = getInt("query/maxWarmingSearchers",Integer.MAX_VALUE); loadPluginInfo(SolrRequestHandler.class,"requestHandler",true, true); loadPluginInfo(QParserPlugin.class,"queryParser",true, true); loadPluginInfo(QueryResponseWriter.class,"queryResponseWriter",true, true); loadPluginInfo(ValueSourceParser.class,"valueSourceParser",true, true); loadPluginInfo(SearchComponent.class,"searchComponent",true, true); loadPluginInfo(QueryConverter.class,"queryConverter",true, true); // this is hackish, since it picks up all SolrEventListeners, // regardless of when/how/why thye are used (or even if they are // declared outside of the appropriate context) but there's no nice // way arround that in the PluginInfo framework loadPluginInfo(SolrEventListener.class, "//listener",false, true); loadPluginInfo(DirectoryFactory.class,"directoryFactory",false, true); loadPluginInfo(IndexDeletionPolicy.class,"mainIndex/deletionPolicy",false, true); loadPluginInfo(IndexReaderFactory.class,"indexReaderFactory",false, true); loadPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain",false, false); //TODO deprecated remove it later loadPluginInfo(SolrHighlighter.class,"highlighting",false, false); if( pluginStore.containsKey( SolrHighlighter.class.getName() ) ) log.warn( "Deprecated syntax found. <highlighting/> should move to <searchComponent/>" ); updateHandlerInfo = loadUpdatehandlerInfo(); Config.log.info("Loaded SolrConfig: " + name); // TODO -- at solr 2.0. this should go away config = this; }<div class="iteye-blog-content-contain" style="font-size: 14px"></div>
相关推荐
通过对SolrDispatchFilter的解析理解solr内部的实际工作原理,让你更清楚其实里面的东西不是很复杂...
旋转检测 要求 torch==1.6 shapely==1.7.1 opencv==4.2.0.34
1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
基于springboot的java毕业&课程设计
智慧藏文化博物馆建设方案PPT(79页)
基于springboot的java毕业&课程设计
动作识别_基于OpenPose实现的实时姿态估计+动作识别_附项目源码_优质项目实战
机器学习之随机森林算法
反弹shell
该系统是针对各类学院或者研究院的项目管理而设计开发的。它实现了项目的各类信息的录入、修改、查询和报表打印等功能,这些信息主要包括项目的基本情况、项目进展程度、项目经费开支、以及科研成果和项目获奖情况等。该系统界面友好清晰,使用方便快捷,它简化了项目的管理过程,提高了科研管理人员的工作效率,从而节省了人力资源与经费开支,有利于经济效益的提高和科研事业的发展。
STM32/GD32 I2C DMA 主从通信 定长主从通信代码示例
课设毕设基于SSM的大学生兼职跟踪系统 LW+PPT+源码可运行.zip
巨灾保险问题及对策研究.docx
卷积神经网络(Convolutional Neural Networks, CNNs 或 ConvNets)是一类深度神经网络,特别擅长处理图像相关的机器学习和深度学习任务。它们的名称来源于网络中使用了一种叫做卷积的数学运算。以下是卷积神经网络的一些关键组件和特性: 卷积层(Convolutional Layer): 卷积层是CNN的核心组件。它们通过一组可学习的滤波器(或称为卷积核、卷积器)在输入图像(或上一层的输出特征图)上滑动来工作。 滤波器和图像之间的卷积操作生成输出特征图,该特征图反映了滤波器所捕捉的局部图像特性(如边缘、角点等)。 通过使用多个滤波器,卷积层可以提取输入图像中的多种特征。 激活函数(Activation Function): 在卷积操作之后,通常会应用一个激活函数(如ReLU、Sigmoid或tanh)来增加网络的非线性。 池化层(Pooling Layer): 池化层通常位于卷积层之后,用于降低特征图的维度(空间尺寸),减少计算量和参数数量,同时保持特征的空间层次结构。 常见的池化操作包括最大池化(Max Pooling)和平均池化(Average Po
Unity插件 Translucent Image 可帮助你构建精美的模糊背景 UI,例如在 iOS/MacOS/Windows 10 Fluent 设计中的 UI。 与许多其他背景模糊解决方案不同,Translucent Image 采用一种对性能影响最小的高效算法,因此用户可以享受更高的帧速率和更长的电池寿命。不仅如此,当你将模糊调高时,它还可以产生完美的平滑效果,而其它资源在高度模糊时会呈现难看的块状图像。
微信小程序设计之相关行业源码及图文导入教程
react中的组件定义
课程设计 基于Python的机器学习的人脸识别系统的设计与实现+详细文档+全部资料(高分项目).zip本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 课程设计 基于Python的机器学习的人脸识别系统的设计与实现+详细文档+全部资料(高分项目).zip本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 课程设计 基于Python的机器学习的人脸识别系统的设计与实现+详细文档+全部资料(高分项目).zip本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 课程设计 基于Python的机器学习的人脸识别系统的设计与实现+详细文档+全部资料(高分项目).zip本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。
微信小程序设计之相关行业源码及图文导入教程
AndroidStudio_WiFiManager-master