亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

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

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

                1問(wèn)題描述

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

                2類(lèi)型轉(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 類(lèi)型具體轉(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類(lèi)型具體轉(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 拆開(kāi),添加如下:比如,_id、_version 也是一個(gè) document,具體看下面的 【2.3 支持 _id 之類(lèi)的字段】 */ for (MetadataFieldMapper metadataMapper : metadataFieldsMappers) { metadataMapper.preParse(context); } if (mapping.root.isEnabled() == false) { // entire type is disabled parser.skipChildren(); } else if (emptyDoc == false) { // 轉(zhuǎn)換對(duì)象或者 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之類(lèi)的字段

                代碼位置: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 等等處理也類(lèi)似。

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

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

                2.4.1類(lèi)型轉(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)換對(duì)象 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 寫(xiě)入每個(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 的字段或者對(duì)象之類(lèi)的,全部加上 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 保持一致。那么,通過(guò) GET docId 這種操作,就可以拿到所有的文檔了。而且,刪除的時(shí)候,特別的方便。算是 ES 這種的一個(gè)方案吧。

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

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

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

                下面貼出來(lái) _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è)例子,其他類(lèi)似。

                3總結(jié)

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

                4其他

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

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

                相關(guān)推薦

                • 園屬于什么結(jié)構(gòu)(園的結(jié)構(gòu)和部首)

                  園 yuán:全包圍結(jié)構(gòu),平穩(wěn)端正中稍帶左收右展。 外部“口” 體態(tài)端莊,稍抗肩,稍帶左輕右重。左豎起筆稍抖,豎身勿重,稍左斜,垂露收筆;第二筆橫折壓著左豎起筆,橫畫(huà)稍抗肩,不要重…

                  2022年11月24日
                • 馬斯克凌晨一點(diǎn)半曬“代碼審查”現(xiàn)場(chǎng),編排他的段子比瘋狂星期四還多

                  夢(mèng)晨 Pine 發(fā)自 凹非寺 量子位 | 公眾號(hào) QbitAI 每一個(gè)真正會(huì)寫(xiě)代碼的人,請(qǐng)?jiān)谙挛?點(diǎn)到總部10層報(bào)到。 每一個(gè)真正會(huì)寫(xiě)代碼的人,請(qǐng)?jiān)谙挛?點(diǎn)到總部10層報(bào)到。 馬斯…

                  2022年11月21日
                • 京東店鋪類(lèi)型有哪些京東入駐有什么資質(zhì)要求

                  今天的互聯(lián)網(wǎng)發(fā)展迅速,讓傳統(tǒng)企業(yè)有了更多選擇,但也同樣也對(duì)剛觸網(wǎng)的商家增添了許多迷茫,近日知舟電商就收到很多商家朋友詢問(wèn)京東入駐相關(guān)問(wèn)題,今天知舟君就給大家分享下。 一.京東入駐準(zhǔn)…

                  2022年11月18日
                • 手淘搜索是自然流量嗎(手淘搜索流量怎么提高)

                  作為一個(gè)賣(mài)家,我們都應(yīng)該知道,現(xiàn)在店鋪的流量大部分來(lái)自移動(dòng)端,也就是我們說(shuō)的手機(jī)端流量。隨著智能手機(jī)的發(fā)展及網(wǎng)速的提升,手機(jī)購(gòu)物已成為常態(tài)。而淘寶也一直嘗試著從一個(gè)購(gòu)物平臺(tái)往社交平…

                  2022年11月18日
                • 怎么刪除自己的追評(píng)(淘寶追評(píng)可以刪除嗎)

                  一、淘寶店鋪每個(gè)評(píng)價(jià)類(lèi)型的處理方案都是不同的,那具體哪些評(píng)價(jià)類(lèi)型該如何區(qū)分呢? 1、主評(píng)為好評(píng)時(shí):不支持修改或者刪除評(píng)價(jià)的,若中評(píng)/差評(píng)改為好評(píng),也不可修改或刪除 ; 2、當(dāng)主評(píng)為…

                  2022年11月17日
                • 第35屆金雞獎(jiǎng)獲獎(jiǎng)名單出爐!頒獎(jiǎng)典禮直播回放入口戳→

                  點(diǎn)擊 藍(lán)字關(guān)注 回復(fù)“金雞”獲取2022廈門(mén)金雞獎(jiǎng)最新消息 昨晚廈門(mén) 成功舉辦了 第35屆金雞獎(jiǎng)?lì)C獎(jiǎng)典禮和電影節(jié)閉幕式 完整獲獎(jiǎng)名單也已出爐 好奇的寶快來(lái)看看吧 第35屆中國(guó)電影金…

                  2022年11月17日
                • 2022新農(nóng)合網(wǎng)上繳費(fèi)入口(新農(nóng)合醫(yī)保網(wǎng)上繳費(fèi)怎么交)

                  目前很多地方的都已經(jīng)開(kāi)通了農(nóng)村合作醫(yī)療保險(xiǎn)自助繳費(fèi)模式,可以選擇網(wǎng)上自助繳費(fèi)! 有些地區(qū)開(kāi)通了新農(nóng)村合作醫(yī)療保險(xiǎn)的微信公眾號(hào),你可以先關(guān)注,然后絆定自己的社會(huì)保障卡,在微信公眾號(hào)平…

                  2022年11月16日
                • 怎么找推廣平臺(tái)網(wǎng)絡(luò)推廣10大優(yōu)質(zhì)平臺(tái)推薦

                  你的關(guān)注就是對(duì)我們最大的肯定。每天一篇原創(chuàng)文章,將華銳視點(diǎn)十年創(chuàng)業(yè)中關(guān)于運(yùn)營(yíng)、程序技術(shù)方面的感悟、走過(guò)的各種坑,分享給你。希望能幫助更多創(chuàng)業(yè)者快速成長(zhǎng),繞過(guò)一些坑。 之前也跟大家介…

                  2022年11月16日
                • 排名前十的小說(shuō)(排名前十的小說(shuō)完結(jié))

                  本文主要講的是排名前十的小說(shuō),以及和排名前十的小說(shuō)完結(jié)相關(guān)的知識(shí),如果覺(jué)得本文對(duì)您有所幫助,不要忘了將本文分享給朋友。 小說(shuō)排行榜2022前十名完結(jié)(十大必看網(wǎng)絡(luò)小說(shuō)排行榜每本都是…

                  2022年11月14日
                • 網(wǎng)站客服代碼(網(wǎng)站客服代碼實(shí)現(xiàn)移動(dòng)端隱藏,電腦端展開(kāi))

                  本文主要講的是網(wǎng)站客服代碼,以及和網(wǎng)站客服代碼實(shí)現(xiàn)移動(dòng)端隱藏,電腦端展開(kāi)相關(guān)的知識(shí),如果覺(jué)得本文對(duì)您有所幫助,不要忘了將本文分享給朋友。 在線客服系統(tǒng)代碼是什么? 在線客服系統(tǒng)代碼…

                  2022年11月12日

                聯(lián)系我們

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