安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

ElasticSearch里我明明指定了long,为什么却变

8月12日 菩提门投稿
  背景
  实体类定义属性id为Long类型,但在调用springdataelasticsearch:3。2。10。RELEASE中的putMapping(Class)方法时却被转换成了keyword类型源码
  查看putMapping方法,可以发现最终调用最下边的重载方法classElasticsearchRestTemplate{。。。OverridepublicTbooleanputMapping(ClassTclazz){returnputMapping(clazz,buildMapping(clazz));}OverridepublicTbooleanputMapping(ClassTclazz,Objectmapping){returnputMapping(getPersistentEntityFor(clazz)。getIndexName(),getPersistentEntityFor(clazz)。getIndexType(),mapping);}OverridepublicTbooleanputMapping(StringindexName,Stringtype,ClassTclazz){returnputMapping(indexName,type,buildMapping(clazz));}OverridepublicbooleanputMapping(StringindexName,Stringtype,Objectmapping){Assert。notNull(indexName,NoindexdefinedforputMapping());Assert。notNull(type,NotypedefinedforputMapping());PutMappingRequestrequestnewPutMappingRequest(indexName)。type(type);if(mappinginstanceofString){request。source(String。valueOf(mapping),XContentType。JSON);}elseif(mappinginstanceofMap){request。source((Map)mapping);}elseif(mappinginstanceofXContentBuilder){request。source((XContentBuilder)mapping);}try{returnclient。indices()。putMapping(request,RequestOptions。DEFAULT)。isAcknowledged();}catch(IOExceptione){thrownewElasticsearchException(FailedtoputmappingforindexName,e);}}。。。}复制代码
  查看buildMapping方法,因为并没有定义外部mappingPath配置文件,所以走最下边的mappingBuilder。buildPropertyMapping(clazz)来进行解析出String类型的json文件abstractclassAbstractElasticsearchTemplate{。。。protectedStringbuildMapping(C?clazz){loadmappingspecifiedinMappingannotationifpresentif(clazz。isAnnotationPresent(Mapping。class)){StringmappingPathclazz。getAnnotation(Mapping。class)。mappingPath();if(!StringUtils。isEmpty(mappingPath)){StringmappingsResourceUtil。readFileFromClasspath(mappingPath);if(!StringUtils。isEmpty(mappings)){}}else{LOGGER。info(mappingPathinMappinghastobedefined。BuildingmappingsusingField);}}buildmappingfromfieldannotationstry{MappingBuildermappingBuildernewMappingBuilder(elasticsearchConverter);returnmappingBuilder。buildPropertyMapping(clazz);}catch(Exceptione){thrownewElasticsearchException(Failedtobuildmappingforclazz。getSimpleName(),e);}}。。。}复制代码
  查看buildPropertyMapping方法classMappingBuilder{。。。StringbuildPropertyMapping(C?clazz)throwsIOException{提前解析出一些通用属性,比如indexName,indexType等等ElasticsearchPersistentE?entityelasticsearchConverter。getMappingContext()。getRequiredPersistentEntity(clazz);构造一个json构造器,以indexType开始XContentBuilderbuilderjsonBuilder()。startObject()。startObject(entity。getIndexType());添加dynamictemplateaddDynamicTemplatesMapping(builder,entity);父子文档判断StringparentTypeentity。getParentType();if(hasText(parentType)){builder。startObject(FIELDPARENT)。field(FIELDTYPE,parentType)。endObject();}属性解析开始标志propertiesbuilder。startObject(FIELDPROPERTIES);具体的properties解析,为根对象非nested对象mapEntity(builder,entity,true,,false,FieldType。Auto,null);builder。endObject()FIELDPROPERTIES。endObject()indexType。endObject()rootobject。close();returnbuilder。getOutputStream()。toString();}privatevoidmapEntity(XContentBuilderbuilder,NullableElasticsearchPersistentEntityentity,booleanisRootObject,StringnestedObjectFieldName,booleannestedOrObjectField,FieldTypefieldType,NullableFieldparentFieldAnnotation)throwsIOException{booleanwriteNestedProperties!isRootObject(isAnyPropertyAnnotatedWithField(entity)nestedOrObjectField);if(writeNestedProperties){StringtypenestedOrObjectField?fieldType。toString()。toLowerCase():FieldType。Object。toString()。toLowerCase();builder。startObject(nestedObjectFieldName)。field(FIELDTYPE,type);if(nestedOrObjectFieldFieldType。NestedfieldTypeparentFieldAnnotation!nullparentFieldAnnotation。includeInParent()){builder。field(includeinparent,parentFieldAnnotation。includeInParent());}builder。startObject(FIELDPROPERTIES);}对象字段属性的解析if(entity!null){entity。doWithProperties((PropertyHandlerElasticsearchPersistentProperty)property{try{if(property。isAnnotationPresent(Transient。class)isInIgnoreFields(property,parentFieldAnnotation)){}buildPropertyMapping(builder,isRootObject,property);}catch(IOExceptione){logger。warn(errormappingpropertywithname{},property。getName(),e);}});}if(writeNestedProperties){builder。endObject()。endObject();}}解析每个property的方法privatevoidbuildPropertyMapping(XContentBuilderbuilder,booleanisRootObject,ElasticsearchPersistentPropertyproperty)throwsIOException{if(property。isAnnotationPresent(Mapping。class)){StringmappingPathproperty。getRequiredAnnotation(Mapping。class)。mappingPath();if(!StringUtils。isEmpty(mappingPath)){ClassPathResourcemappingsnewClassPathResource(mappingPath);if(mappings。exists()){builder。rawField(property。getFieldName(),mappings。getInputStream(),XContentType。JSON);}}}geo标识booleanisGeoPointPropertyisGeoPointProperty(property);completion标识booleanisCompletionPropertyisCompletionProperty(property);nestedobject标识booleanisNestedOrObjectPropertyisNestedOrObjectProperty(property);属性上的Field注解FieldfieldAnnotationproperty。findAnnotation(Field。class);if(!isGeoPointProperty!isCompletionPropertyproperty。isEntity()hasRelevantAnnotation(property)){if(fieldAnnotationnull){}I?extendsTypeI?iteratorproperty。getPersistentEntityTypes()。iterator();ElasticsearchPersistentE?persistentEntityiterator。hasNext()?elasticsearchConverter。getMappingContext()。getPersistentEntity(iterator。next()):mapEntity(builder,persistentEntity,false,property。getFieldName(),isNestedOrObjectProperty,fieldAnnotation。type(),fieldAnnotation);if(isNestedOrObjectProperty){}}MultiFieldmultiFieldproperty。findAnnotation(MultiField。class);if(isGeoPointProperty){applyGeoPointFieldMapping(builder,property);}if(isCompletionProperty){CompletionFieldcompletionFieldproperty。findAnnotation(CompletionField。class);applyCompletionFieldMapping(builder,property,completionField);}判断是否为id属性if(isRootObjectfieldAnnotation!nullproperty。isIdProperty()){applyDefaultIdFieldMapping(builder,property);}elseif(multiField!null){addMultiFieldMapping(builder,property,multiField,isNestedOrObjectProperty);}elseif(fieldAnnotation!null){addSingleFieldMapping(builder,property,fieldAnnotation,isNestedOrObjectProperty);}}。。。}复制代码
  至此可以看到,只要fieldName为id或document就判定为是id属性,然后将type设置为keyword并且可被索引。疑问到这里解决classSimpleElasticsearchPersistentProperty{。。。privatestaticfinalListStringSUPPORTEDIDPROPERTYNAMESArrays。asList(id,document);publicSimpleElasticsearchPersistentProperty(Propertyproperty,PersistentE?,ElasticsearchPersistentPropertyowner,SimpleTypeHoldersimpleTypeHolder){。。。this。isIdsuper。isIdProperty()SUPPORTEDIDPROPERTYNAMES。contains(getFieldName());。。。}OverridepublicbooleanisIdProperty(){returnisId;}privatevoidapplyDefaultIdFieldMapping(XContentBuilderbuilder,ElasticsearchPersistentPropertyproperty)throwsIOException{builder。startObject(property。getFieldName())。field(FIELDTYPE,TYPEVALUEKEYWORD)。field(FIELDINDEX,true)。endObject();}。。。}复制代码话外题
  项目中使用的ElasticSearch实体类都是采取Document指定indexName来操作的,但是索引和表都涉及到分库分表,所以又不能写死,然后就采取的SpEL配合ThreadLocal从上下文里set后get,其实Spring对elasticsearch操作类似于关系型数据库也封装的有一层Repository抽象,名为ElasticsearchRepository,我们可以直接定义实体类操作接口继承就可以完成对单索引的CRUD以及Page等操作,但这样有一个问题,那就是indexName无法动态去调整,所以就放弃了这种,改用更底层的RestHighLevelClient封装的ElasticSearchRestTemplate模版类,这样在面对分库分表时就可以手动去对每个Document进行set不同的indexName,跨索引查询时也可以指定多个,也可以直接指定索引的alias,需要注意的时,在进行更新时,只指定alias是不被允许的,需要手动查出符合条件的Document在进行索引的分组批量更新,即调用ElasticSearch的bulkapi
  在对ElasticSearch和数据库的一致性问题上,我是通过封装不同的方法来确保强一致性和最终一致性强一致性
  类似插入、更新、删除等场景下,都是放在一个事务里,先操作数据库,再操作ElasticSearch,这样可以确保操作ElasticSearch失败时,数据库可以成功回滚。一般只运用于对数据实时性要求敏感的场景,并且数据量不大的情况,但即便这样还是会有至少1s的延迟,这里就涉及到ElasticSearch的刷盘策略问题上了,这里不展开研究最终一致性
  批量的插入、更新这些操作,如果放在一个大事务里,对数据库也是一种压力,所以一般是分批操作数据库,另起一个线程池对事务提交进行监听,将数据库数据同步到ElasticSearch里,在同步成功后反转数据库的同步状态字段。为了确保万无一失,后台会启动一个定时扫描数据库同步字段的线程去定时扫描同步。这种一般适用于大数据量的场景。当然你也可以去监听MySQL的binlog日志来进行同步。
投诉 评论 转载

小米困于低端,华为困于4G,苹果拿下65的高端市场马上iPhone13又要发布了,虽然这一代的iPhone13并不会有大改进,甚至被人表示叫iPhone12S可能更合适。但不可否认的是,这次的iPhone13依然会非常抢……一觉醒来,行业没了!比特币遭多国监管围剿,阿里巴巴国际站禁售华夏时报(www。chinatimes。net。cn)记者赵奕胡金华上海报道9月27日晚,阿里巴巴国际站官方发布《关于禁售虚拟货币矿机类产品的公告》。公告表示,根据……乘客付款154元,司机收款95元,新华社披露滴滴抽成高,谁之上周去高铁站,打车时候显示滴滴快车预估105,然后我就付款,付款就变成136了,没注意看指纹识就付款成功了,立马就有司机接单,别想着赶时间就没取消,上车跟司机聊天他说他那里一口……ElasticSearch里我明明指定了long,为什么却变背景实体类定义属性id为Long类型,但在调用springdataelasticsearch:3。2。10。RELEASE中的putMapping(Class)方法时却被……互联网卖服务的思路,一切来源生活每个项目都不是那么容易做的,在互联网赚钱,无非就是那么几个版块:卖产品、卖技术、卖服务、卖广告。而我今天就是要给你讲讲其中的一个,卖服务。所谓的卖服务,我们生活中就……微软从苹果挖了一个顶级芯片工程师本文转载自【半导体行业观察】公众号根据知情人士透露,微软公司已从苹果公司挖角一位资深芯片设计师,此时正值微软寻求扩大发展自家的服务器芯片。消息人士说,离开苹果的菲利……大牛港股收评3月23日港股三大指数收涨,恒指涨1。21,国指涨1。28,恒生科技指数涨2。05。截至收盘,港股今日上涨1193只,下跌788只,收平882只。板块方面,科网股向……相对于其他充电品牌,小鲸云隔空充电具有哪些优势?穿透间距大,快速充电:带手机外壳也可以稳定的充电,平稳地隔空无线充电间距最大可以达到3cm。在保证过压,过流,过充等安全性能下依然能兼容18W高速无线充电。感应速度快,便……更好用更安全的手机系统OriginOSOcean体验最近新发布的vivoS12Pro搭载了OriginOSOcean系统,这两天试过之后,我感觉它在很多交互设计以及功能方面,都有着非常出色的表现,用过一段时间之后,确实可以大大提……图拉斯G10真无线体验低调轻奢配置均衡图拉斯是国内最早一批做真无线的厂商了,记得好几年前购买的第一款真无线耳机就是图拉斯的H8,不过当时真无线属于发展初期,性能和功能方面都不太完善,不过仍然获得了不一样的潮流感受。……网易市场已不足腾讯的14!坚决出海的背后,是腾讯钳制的困境网易的行业老二地位其实已经很多年了。但其实,网易的行业老二的位置,多少有些名不副实。为什么这么说,据伽马数据显示,腾讯的市场占比已经达到了50。4,已经是名副其实的半壁江……ASML同意出售光刻机,中芯却一直扩大28nm产能,为何不冲芯片产业,外忧内患并存。在中国本土芯片的解围纾困之战中,首先抵达14nm工艺的排头兵中芯国际,12个月之内,在北京、深圳两地,投入百亿美金,两度大幅扩增28nm及12英寸晶圆产……
网络安全公司Mandiant遭股东诉讼提供的谷歌收购信息存在圈子功能圈子功能以企业总部看全球五大通信设备供应商,三星中兴以超高层引领华强北内幕iPhone这几款出货量极低,大伙别被割韭菜聚焦国产操作系统爱捷云与银河麒麟完成兼容互认证亚马逊跟卖怎么找产品?需要注意这几个问题全能windows系统维护军刀GlaryUtilitiesP性价比极高的骁龙870手机,12GB256GB重回2299元马老师现身海南,2022年首次露面1999起售,RedmiK40游戏增强版真不像游戏手机成都车展百公里综合油耗1L,奇瑞首推混动车型英研究报告揭示最无聊的工作和爱好失孤原型24年后终于父子相认,热搜背后的几点反思害怕文案写作的时候,我们怕的是什么?《巧渡金沙江》读后感(三篇)悬疑剧回来的女儿将播张子枫梅婷王砚辉实力主演老酒馆由麻子是好是坏由麻子向陈怀海道歉把橘子皮扔掉的人最傻!橘子皮的这些功效鲜有人知道眼科手术室规范化管理对策分析论文我好想变成一只小鸟的作文400字什么是瓜尔胶瓜尔胶和黄原胶的区别题李彭州南亭老师英文(千万别喊老师Teacher)公司融资需要什么资料?

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利