免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      ES 源碼分析之?dāng)?shù)據(jù)類型轉(zhuǎn)換

      公司有的小伙伴問我,為什么不推薦我們使用 nested 結(jié)構(gòu)呢,還說性能低。那么,ES 針對 nested 之類的結(jié)構(gòu)。因?yàn)镋S 源碼我也基本看完了。索性,直接寫成筆記。比直接在代碼里面寫注釋來的更舒心點(diǎn)。

      1問題描述

      • ES 是 lucene 不僅僅是集群版的概念,還有涉及到支持豐富的數(shù)據(jù)類型。如 nested 、object 等等結(jié)構(gòu)。它是怎么支持的呢?
      • ES 還支持 _id、_version 等等字段。這種是怎么存儲(chǔ)的呢?
      • 聽說 ES 的 parent doc 和 nested doc 是分開來存儲(chǔ)的,那么獲取的時(shí)候,他們是通過哪種關(guān)系關(guān)聯(lián)的呢?

      2類型轉(zhuǎn)換

      2.1初步代碼入口

      代碼具體入口 org.elasticsearch.index.shard.IndexShard#prepareIndex

      public static Engine.Index prepareIndex(DocumentMapperForType docMapper, SourceToParse source, long seqNo, long primaryTerm, long version, VersionType versionType, Engine.Operation.Origin origin, long autoGeneratedIdTimestamp, boolean isRetry, long ifSeqNo, long ifPrimaryTerm) { long startTime = System.nanoTime(); // 涉及到 nested 等等結(jié)構(gòu)的轉(zhuǎn)換,直接看【2.2 類型具體轉(zhuǎn)換代碼】 ParsedDocument doc = docMapper.getDocumentMapper().parse(source); // Mapping 是否要處理 if (docMapper.getMapping() != null) { doc.addDynamicMappingsUpdate(docMapper.getMapping()); } // _id 轉(zhuǎn) uid。這里是為了數(shù)據(jù)能保持整齊,方便壓縮??梢詤⒖?【哈夫曼編碼】。 Term uid = new Term(IdFieldMapper.NAME, Uid.encodeId(doc.id())); return new Engine.Index(uid, doc, seqNo, primaryTerm, version, versionType, origin, startTime, autoGeneratedIdTimestamp, isRetry, ifSeqNo, ifPrimaryTerm); }

      2.2類型具體轉(zhuǎn)換代碼

      /** * 內(nèi)部轉(zhuǎn)換文檔,如果有 nested 結(jié)構(gòu),需要再次轉(zhuǎn)換一下 * @param mapping * @param context * @param parser * @throws IOException */ private static void internalParseDocument(Mapping mapping, MetadataFieldMapper[] metadataFieldsMappers, ParseContext context, XContentParser parser) throws IOException { final boolean emptyDoc = isEmptyDoc(mapping, parser); /** * 預(yù)處理,為 root document 拆開,添加如下:比如,_id、_version 也是一個(gè) document,具體看下面的 【2.3 支持 _id 之類的字段】 */ for (MetadataFieldMapper metadataMapper : metadataFieldsMappers) { metadataMapper.preParse(context); } if (mapping.root.isEnabled() == false) { // entire type is disabled parser.skipChildren(); } else if (emptyDoc == false) { // 轉(zhuǎn)換對象或者 nested 結(jié)構(gòu),這個(gè)方法會(huì)反復(fù)遞歸調(diào)用。主要是 object 結(jié)構(gòu)或者 nested 結(jié)構(gòu) parseObjectOrNested(context, mapping.root); } // 為各個(gè)非 root document 添加 _version 等等字段 for (MetadataFieldMapper metadataMapper : metadataFieldsMappers) { metadataMapper.postParse(context); } }

      2.3前置處理之支持_id之類的字段

      代碼位置:org.elasticsearch.index.mapper.MetadataFieldMapper#preParse下面只貼出 _id 的處理

      /** * _id 也是一個(gè) doc * @param context */ @Override public void preParse(ParseContext context) { BytesRef id = Uid.encodeId(context.sourceToParse().id()); context.doc().add(new Field(NAME, id, Defaults.FIELD_TYPE)); }

      這里只是了其中的一個(gè)例子:_id ,其他的比如 _version、_seqno、_source 等等處理也類似。

      2.4轉(zhuǎn)換復(fù)雜的結(jié)構(gòu),比如nested結(jié)構(gòu)

      ES 在轉(zhuǎn)換 nested 結(jié)構(gòu)的時(shí)候,比較有意思。

      2.4.1類型轉(zhuǎn)換整體入口

      /** * 轉(zhuǎn)換 object 或者 nested 結(jié)構(gòu)的,這里會(huì)出現(xiàn)遞歸調(diào)用,主要是為了解決 object、nested 結(jié)構(gòu) * @param context * @param mapper * @throws IOException */ static void parseObjectOrNested(ParseContext context, ObjectMapper mapper) throws IOException { if (mapper.isEnabled() == false) { context.parser().skipChildren(); return; } XContentParser parser = context.parser(); XContentParser.Token token = parser.currentToken(); if (token == XContentParser.Token.VALUE_NULL) { // the object is null (“obj1” : null), simply bail return; } String currentFieldName = parser.currentName(); if (token.isValue()) { throw new MapperParsingException(“object mapping for [” + mapper.name() + “] tried to parse field [” + currentFieldName + “] as object, but found a concrete value”); } ObjectMapper.Nested nested = mapper.nested(); // 如果是 nested 結(jié)構(gòu),每次都會(huì)new 一個(gè)空白的 document ,而且,這個(gè)方法 #{innerParseObject},是遞歸實(shí)現(xiàn),把 object 或者 document 變成多個(gè) document if (nested.isNested()) { // 進(jìn)入下方的:【2.4.2 nested 轉(zhuǎn)換初步入口】 context = nestedContext(context, mapper); } // if we are at the end of the previous object, advance if (token == XContentParser.Token.END_OBJECT) { token = parser.nextToken(); } if (token == XContentParser.Token.START_OBJECT) { // if we are just starting an OBJECT, advance, this is the object we are parsing, we need the name first token = parser.nextToken(); } // 轉(zhuǎn)換對象 innerParseObject(context, mapper, parser, currentFieldName, token); // restore the enable path flag if (nested.isNested()) { nested(context, nested); } }

      2.4.2nested轉(zhuǎn)換初步入口

      /** * 內(nèi)部轉(zhuǎn)換 nested 結(jié)構(gòu),生成一個(gè)空白的 nested 結(jié)構(gòu) * TODO nested 文檔的 _id 既然跟父文檔的一樣,lucene 寫入每個(gè) doc ,都是拼接。那么,在get 的時(shí)候,自然會(huì)獲取到相同的 _id 多個(gè)文檔,包含了 nested 結(jié)構(gòu)。然后,再內(nèi)部轉(zhuǎn)換為我們 最想要的結(jié)果。 * @param context * @param mapper * @return */ private static ParseContext nestedContext(ParseContext context, ObjectMapper mapper) { // 創(chuàng)建 nested 上下文,并且,new 一個(gè)空白的 document。為后面的 nested 的字段或者對象之類的,全部加上 context = context.createNestedContext(mapper.fullPath()); ParseContext.Document nestedDoc = context.doc(); ParseContext.Document parentDoc = nestedDoc.getParent(); // We need to add the uid or id to this nested Lucene document too, // If we do not do this then when a document gets deleted only the root Lucene document gets deleted and // not the nested Lucene documents! Besides the fact that we would have zombie Lucene documents, the ordering of // documents inside the Lucene index (document blocks) will be incorrect, as nested documents of different root // documents are then aligned with other root documents. This will lead tothe nested query, sorting, aggregations // and inner hits to fail or yield incorrect results. IndexableField idField = parentDoc.getField(IdFieldMapper.NAME); if (idField != null) { // We just need to store the id as indexed field, so that IndexWriter#deleteDocuments(term) can then // delete it when the root document is deleted too. nestedDoc.add(new Field(IdFieldMapper.NAME, idField.binaryValue(), IdFieldMapper.Defaults.NESTED_FIELD_TYPE)); } else { throw new IllegalStateException(“The root document of a nested document should have an _id field”); } // the type of the nested doc starts with __, so we can identify that its a nested one in filters // note, we don’t prefix it with the type of the doc since it allows us to execute a nested query // across types (for example, with similar nested objects) nestedDoc.add(new Field(TypeFieldMapper.NAME, mapper.nestedTypePathAsString(), TypeFieldMapper.Defaults.NESTED_FIELD_TYPE)); return context; }

      仔細(xì)看看里面的英文。主要的一點(diǎn)是:nested 結(jié)構(gòu)的 _id 和 parent 的 _id 保持一致。那么,通過 GET docId 這種操作,就可以拿到所有的文檔了。而且,刪除的時(shí)候,特別的方便。算是 ES 這種的一個(gè)方案吧。

      2.4.3數(shù)據(jù)處理

      每個(gè)字段的填充入口在:org.elasticsearch.index.mapper.DocumentParser#innerParseObject這里是一個(gè)遞歸調(diào)用的操作。比較繞。

      2.5后置處理之設(shè)置_version等等

      下面貼出來 _version 的處理代碼的入口:org.elasticsearch.index.mapper.VersionFieldMapper#postParse,可以看看具體的實(shí)現(xiàn)。

      @Override public void postParse(ParseContext context) { // In the case of nested docs, let’s fill nested docs with version=1 so that Lucene doesn’t write a Bitset for documents // that don’t have the field. This is consistent with the default value for efficiency. Field version = context.version(); assert version != null; for (Document doc : context.nonRootDocuments()) { // 為此 doc 添加一個(gè) _version 字段 doc.add(version); } }

      這里支持舉了 _version 舉個(gè)例子,其他類似。

      3總結(jié)

      • ES 是 lucene 不僅僅是集群版的概念,還有涉及到支持豐富的數(shù)據(jù)類型。如 nested 、object 等等結(jié)構(gòu)。它是怎么支持的呢?答:ES 針對 nested 、object 直接拍平處理
      • ES 還支持 _id、_version 等等字段。這種是怎么存儲(chǔ)的呢?答:ES 針對 _id 、_version 是保存為獨(dú)立的文檔的。
      • 聽說 ES 的 parent doc 和 nested doc 是分開來存儲(chǔ)的,那么獲取的時(shí)候,他們是通過那種關(guān)系關(guān)聯(lián)的呢?答:通過 root Doc 的 ID 來做關(guān)聯(lián)的。

      4其他

      后續(xù)請關(guān)注 ES 寫入流程。讓我們看看 ES 是如何處理分布式請求及保證高可用的。

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      (0)
      用戶投稿
      上一篇 2022年6月28日 17:26
      下一篇 2022年6月28日 17:26

      相關(guān)推薦

      • 安全管理框架,用Shiro還是用Spring Security?

        開發(fā)Java應(yīng)用項(xiàng)目的時(shí)候,安全管理通常來講是必不可少的功能。常用的安全管理框架有Apache Shiro和Spring Security,那么作為一名開發(fā)人員的話,該如何選擇自己…

        2022年6月16日
      • 結(jié)構(gòu)體類型變量應(yīng)用舉例

        現(xiàn)實(shí)生活中存在的大部分對象具有不同的屬性,需要用不同的數(shù)據(jù)類型去描述。類如,一個(gè)公司員工的信息包括工號,姓名,性別,年齡,工資等。這些屬性都是有聯(lián)系的,因?yàn)樗麄儗儆谕粋€(gè)員工。為了…

        2022年6月23日
      • 詳解 Java 17 中的模式匹配(Pattern Matching)

        提到模式匹配(Pattern Matching),Java 開發(fā)人員可能會(huì)比較陌生。實(shí)際上,其他編程語言的開發(fā)人員早就已經(jīng)使用過模式匹配了。JVM 上的編程語言 Scala 的模式…

        2022年9月4日
      • 邀您一起見證11位女性編碼藝術(shù)家和藝術(shù)編碼家生成綻放(一起見證公司的發(fā)展)

        Chamcha是以NFT為中心的的區(qū)塊鏈線上交易所,始創(chuàng)把NFT做到全網(wǎng)全鏈。Chamcha交易所里面用戶可以通過相對比較簡單的方式入門NFT,包括用信用卡或USDC穩(wěn)定幣就可以購…

        2022年11月2日
      • 科學(xué)家最新發(fā)現(xiàn)冰的第18個(gè)狀態(tài)-“超離子導(dǎo)體冰”

        科學(xué)家在兩顆鉆石之間壓縮了一個(gè)水滴,并使用世界上最強(qiáng)大的激光器將其轟擊至類似恒星的溫度,結(jié)果形成了一種神秘的水狀態(tài)。目前科學(xué)家將其稱為“超離子導(dǎo)體冰”,這是迄今為止發(fā)現(xiàn)最特殊的冰結(jié)…

        2022年8月16日
      • 在多數(shù)大滅絕發(fā)生前,都經(jīng)歷過一個(gè)相同的事件

        集群滅絕指的是那些在地質(zhì)時(shí)間尺度上很短一段時(shí)間里,絕大部分生命被完全抹去的事件。在地球的生命史上,集群滅絕反復(fù)出現(xiàn)。除了眾所周知的五次著名的大滅絕事件之外,已知的集群滅絕事件其實(shí)還…

        2022年9月18日
      • 中國干細(xì)胞制造市場報(bào)告、及市場預(yù)測

        干細(xì)胞制造是指培養(yǎng)從骨髓或外周血細(xì)胞獲得的細(xì)胞的過程。干細(xì)胞具有在體內(nèi)發(fā)育成特殊細(xì)胞類型的獨(dú)特能力。干細(xì)胞制造市場的企業(yè)競爭態(tài)勢 該報(bào)告涉及的主要國際市場參與者有Thermo Fi…

        2022年7月3日
      • Atomic 原子類詳細(xì)介紹

        Atomic 翻譯成中文是原子的意思。在化學(xué)上,我們知道原子是構(gòu)成一般物質(zhì)的最小單位,在化學(xué)反應(yīng)中是不可分割的。在我們這里 Atomic 是指一個(gè)操作是不可中斷的。即使是在多個(gè)線程…

        2022年7月5日
      • 中國6大“光瓶酒”,價(jià)格親民,皆為純糧酒,懂酒的人常喝

        說起口糧酒,大部分酒友的首選都是光瓶酒,雖然光瓶酒看上去廉價(jià),但卻有著很高的性價(jià)比,適合日常飲用。 但常和光瓶酒一同出現(xiàn)的,除了有高性價(jià)比之外,還有“酒精酒”。 光瓶酒可謂是酒精酒…

        2022年8月21日
      • Java學(xué)習(xí)筆記(三):結(jié)構(gòu)性語句

        結(jié)構(gòu)性語句 結(jié)構(gòu)性語句主要有順序結(jié)構(gòu)、選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu)三種,下面分別進(jìn)行介紹。 順序結(jié)構(gòu): 顧名思義,順序結(jié)構(gòu)就是從上往下依次執(zhí)行,這個(gè)比較簡單,不用再多說。其實(shí)其他結(jié)構(gòu)性語句的…

        2022年7月19日

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息