国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于數(shù)據(jù)庫的全文檢索實現(xiàn)

這篇具有很好參考價值的文章主要介紹了基于數(shù)據(jù)庫的全文檢索實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

對于內(nèi)容摘要,信件內(nèi)容進行全文檢索
基于SpringBoot 2.5.6+Postgresql+jpa+hibernate實現(xiàn)

依賴

<spring-boot.version>2.5.6</spring-boot.version>
<hibernate-types-52.version>2.14.0</hibernate-types-52.version>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- hibernate支持配置 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
</dependency>
<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>${hibernate-types-52.version}</version>
</dependency>
<!-- hibernate支持配置 -->
 
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
</dependency>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

業(yè)務(wù)邏輯

登記保存之后,處理完成業(yè)務(wù)邏輯,發(fā)送全文檢索事件

//附加類型對應(yīng)的附件ids
Map<String, List<String>> attCategoryToAttIds = new HashMap<String, List<String>>();
attCategoryToAttIds.put(cmpRecord.getFileCategory(), files==null?null:files.stream().map(d->d.getId()).collect(Collectors.toList()));
//處理監(jiān)聽事件所需要的數(shù)據(jù)
Map<String,Object>eventData = Utils.buildMap("recordId", cmpRecord.getId(),"newRecord", true,"attCategoryToAttIds", attCategoryToAttIds);
//創(chuàng)建全文檢索事件
DomainEvent de = new DefaultDomainEvent(cmpRecord.getId() + "_Handle_CmpRecord_FullTextSearch", operateInfo, ExecutePoint.CURR_THREAD,
                eventData, new Date(), "Handle_CmpRecord_FullTextSearch");
//發(fā)布事件
DomainEventPublisherFactory.getRegisteredPublisher().publishEvent(de);

處理業(yè)務(wù)發(fā)送全文檢索事件

@Service
@Transactional
@SuppressWarnings("unchecked")
public class HandleCmpRecordFullTextSearchListener implements IDomainEventListener {
    
    @Autowired
    private CmpRecordRepository cmpRecordRepository;
    @Autowired
    private DataChangeLogEventRepository dataChangeLogEventRepository;
    
    @Override
    public void onEvent(DomainEvent event) {
        AccessTokenUser operator=event.getOperator();
        Date operateTime=event.obtainEventTime();
        Map<String,Object> otherData=(Map<String,Object>)event.getEventData();
        String recordId = (String) otherData.get("recordId");
        boolean newRecord=(boolean)otherData.get("newRecord");
        String comment = (String) otherData.get("comment");//辦理記錄的備注
        if(StringUtils.isBlank(recordId)) {
            throw new RuntimeException("未指定信訪記錄id");
        }
     	//獲取登記信息
        CmpRecord cmdRecord = cmpRecordRepository.getCmpRecordById(recordId);
        //指定關(guān)聯(lián)關(guān)系
        RelateProjValObj cmpRdProj=new RelateProjValObj(recordId,RelateProjConstants.PROJTYPE_CMP_RECORD); 
        //這是關(guān)聯(lián)那個業(yè)務(wù)
        List<RelateProjValObj> mainProjs=Arrays.asList(cmpRdProj);
        DomainEvent de=null;
        //登記信息是無效的 則刪除已存在的和這個件相關(guān)的
        if(cmdRecord==null||!cmdRecord.isValidEntity()) {
            //刪除全文檢索信息
            de=new FullTextSearchOperateEvent(recordId+"_FullTextSearch_Remove", null, operator, operateTime,
                    mainProjs, null);
            DomainEventPublisherFactory.getRegisteredPublisher().publishEvent(de);
            return;
        }
        //全文檢索 類型前綴 
        String contentTypepPefix=RelateProjConstants.PROJTYPE_CMP_RECORD;
        //在當(dāng)前線程中執(zhí)行,保證事務(wù)一致性
        ExecutePoint executePoint=ExecutePoint.CURR_THREAD;
        
        /***********************************************關(guān)鍵詞檢索-內(nèi)容摘要***********************************************/
        //全文檢索的類型 區(qū)分內(nèi)容摘要 附件內(nèi)容
        List<String> contentTypes=Arrays.asList(contentTypepPefix+"_contentAbstract");
        String contentAbstract =cmdRecord.getBaseInfo().getContentAbstract();//內(nèi)容摘要
        if(StringUtils.isBlank(contentAbstract)) contentAbstract="";
        if(StringUtils.isNotBlank(comment)) {
            if(StringUtils.isNotBlank(contentAbstract)) contentAbstract=contentAbstract + ",";
            contentAbstract=contentAbstract+comment;
        }
        de=new FullTextSearchOperateEvent(recordId+"_FullTextSearch_Update", executePoint, operator, operateTime,
                mainProjs, contentTypes, contentAbstract, null);
        DomainEventPublisherFactory.getRegisteredPublisher().publishEvent(de);
        
        /***********************************************關(guān)鍵詞檢索-信件內(nèi)容***********************************************/
        contentTypes=Arrays.asList(contentTypepPefix+"_content");
        String content =cmdRecord.getBaseInfo().getContent();//信件內(nèi)容
        de=new FullTextSearchOperateEvent(recordId+"_FullTextSearch_Update", executePoint, operator, operateTime,
                mainProjs, contentTypes, content, null);
        DomainEventPublisherFactory.getRegisteredPublisher().publishEvent(de);
        
        /***********************************************關(guān)鍵詞檢索-附件(原信等)***********************************************/
        //如果附件也需要檢索  設(shè)置attIds參數(shù)
        Map<String,List<String>> attCategoryToAttIds=(Map<String,List<String>>)otherData.get("attCategoryToAttIds");
        if(attCategoryToAttIds!=null && attCategoryToAttIds.size() > 0) {
            //按附件類型分開
            for (Map.Entry<String,List<String>> d : attCategoryToAttIds.entrySet()) {
                contentTypes=Arrays.asList(contentTypepPefix+"_att_"+d.getKey());
                List<String> attIds=d.getValue();//公文相關(guān)附件
                de=new FullTextSearchOperateEvent(recordId+"_att_"+d.getKey()+"_FullTextSearch_Update", executePoint,
                        operator, operateTime, mainProjs, contentTypes, null, attIds);
                DomainEventPublisherFactory.getRegisteredPublisher().publishEvent(de);
            }
        }
    }
    
    @Override
    public boolean listenOn(String eventType) {
        return "Handle_CmpRecord_FullTextSearch".equals(eventType);
    }
}

統(tǒng)一處理全文檢索事件

@Service
@Transactional
public class FullTextSearchListener extends JpaHibernateRepository implements IDomainEventListener{
    
	@Autowired
	private FullTextSearchRepository fullTextSearchRepository;
	@Autowired
	private IFileSysService fileSysService;
	
    @Override
    public void onEvent(DomainEvent event) {
    	if("true".equals(BaseConstants.getProperty("prefetchingRecordNo", "false"))){
    		return;
    	}
        FullTextSearchOperateEvent de = null;
        if(event instanceof FullTextSearchOperateEvent) {
        	de=(FullTextSearchOperateEvent)event;
        }
        if(de==null) {
        	return;
        }
        if(FullTextSearchOperateEvent.EVENTTYPE_UPDATE.equals(de.getEventType())) {
        	/**
        	 "mainProjs":List<RelateProjValObj> 必選
        	 "contentType":String 必選
        	 "content":String 可選
        	 "attIds":List<String> 可選  content與attIds都不存在 會刪除對應(yīng)關(guān)鍵詞檢索
        	 "relProjs":List<RelateProjValObj> 可選  指定的需要添加的關(guān)系
        	 "removeOtherRelProjs":false  可選  是否清除 指定relProjs以外的關(guān)聯(lián)記錄
        	 */
        	this.fullTextSearchUpdate(de);
        }else if(FullTextSearchOperateEvent.EVENTTYPE_REMOVE.equals(de.getEventType())) {
        	/**
        	 "mainProjs":List<RelateProjValObj> 必選
        	 */
        	this.fullTextSearchRemoveByProjs(de);
        }
    }
    
	//關(guān)鍵詞檢索增加
	private void fullTextSearchUpdate(FullTextSearchOperateEvent de) {
		Date date=de.obtainEventTime();
		if(date==null) {
			date=new Date();
		}
		List<RelateProjValObj> mainProjs=de.getMainProjs();
		String contentType=null;
		if(de.getContentTypes()!=null&&de.getContentTypes().size()==1) {
			contentType=de.getContentTypes().get(0);
		}
		String content=de.getContent();
		List<String> attIds=de.getAttIds();
		if(mainProjs==null||mainProjs.size()==0
				||StringUtils.isBlank(contentType)
				) {
			throw new RuntimeException("數(shù)據(jù)指定錯誤");
		}
		Set<String> fullTextIds=new HashSet<String>();
		for (RelateProjValObj mainProj : mainProjs) {
			if(StringUtils.isBlank(mainProj.getProjId())||StringUtils.isBlank(mainProj.getProjType())) {
				continue;
			}
			fullTextIds.add(new FullTextSearch(mainProj,contentType,null,null).getId());
		}
		if(fullTextIds.size()==0) {
			throw new RuntimeException("數(shù)據(jù)指定錯誤");
		}
		//這是從附件中獲取文本數(shù)據(jù)
		if(StringUtils.isBlank(content)&&attIds!=null) {
			content="";
			try {
				if(attIds.size()>0) {
					Map<String,String> attIdToContentMao=ThreadLocalCache.fetchAPIData(null,()->{
						return fileSysService.findFileContentByIds(attIds, true);
					});
					for (String attContent : attIdToContentMao.values()) {
						if(StringUtils.isBlank(attContent)) {
							continue;
						}
						if(StringUtils.isNotBlank(content)) {
							content+=",";
						}
						content+=RegExUtils.replaceAll(attContent, "\\u0000", "");//處理掉非法字符
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		//從數(shù)據(jù)庫中獲取已經(jīng)存的
		List<FullTextSearch> oldFullTexts=this.fullTextSearchRepository.findFullTextSearchByIds(fullTextIds);
		Map<String,FullTextSearch> oldFullTextMap=oldFullTexts.stream().collect(Collectors.toMap(d->d.getId(),d->d));
		//遍歷這次需要更新的記錄
		for (RelateProjValObj mainProj : mainProjs) {
			if(StringUtils.isBlank(mainProj.getProjId())||StringUtils.isBlank(mainProj.getProjType())) {
				continue;
			}
			FullTextSearch fullText=new FullTextSearch(mainProj, contentType, content, date);
			
			FullTextSearch oldFullText=oldFullTextMap.get(fullText.getId());
			//舊的記錄中已存在 則更新
			if(oldFullText!=null) {
				if(StringUtils.isBlank(content)) {
				//如果內(nèi)容未空 則刪除	
				this.fullTextSearchRepository.removeFullTextSearch(oldFullText);
					return;
				}
				//如果存在內(nèi)容,則更新
				this.fullTextSearchRepository
				.updateFullTextSearchContent(fullText.getId(), content, date);
			}else {
				if(StringUtils.isBlank(content)) {
					return;
				}
				try {//否則 創(chuàng)建全文檢索記錄
					this.fullTextSearchRepository.createFullTextSearch(fullText);
				} catch (Exception e) {
					e.printStackTrace();
					return;
				}
			}
			
		}
	}
	
	//關(guān)鍵詞檢索刪除  根據(jù)主相關(guān)件
	private void fullTextSearchRemoveByProjs(FullTextSearchOperateEvent de) {
		Date date=de.obtainEventTime();
		if(date==null) {
			date=new Date();
		}
		List<RelateProjValObj> mainProjs=de.getMainProjs();
		if(mainProjs==null||mainProjs.size()==0) {
			throw new RuntimeException("數(shù)據(jù)指定錯誤");
		}
		
		List<String> projKeys=new ArrayList<String>();
		for (RelateProjValObj mainProj : mainProjs) {
			projKeys.add(mainProj.getProjKey());
		}
		Map<String,Object> params=new HashMap<String,Object>();
		StringBuffer hql=new StringBuffer();
		hql.append("delete from ").append(FullTextSearch.class.getName()).append(" ");
		hql.append("where mainProj.projKey IN(:projKeys) ");
		params.put("projKeys", projKeys);
		if(de.getContentTypes()!=null&&de.getContentTypes().size()>0) {
			params.put("contentTypes", de.getContentTypes());
		}
		this.createHQLQueryByMapParams(hql.toString(), params).executeUpdate();
	}
	
	@Override
    public boolean listenOn(String eventType) {
        return eventType.startsWith(FullTextSearchOperateEvent.class.getName());
    }
}

全文檢索實體

@Entity
@Table(
    name="TV_FULLTEXT_SEARCH",
    indexes={
        @Index(name="idx_TV_FULLTEXT_SEARCH1",columnList="projKey"),
        @Index(name="idx_TV_FULLTEXT_SEARCH2",columnList="contentType")
    }
)
public class FullTextSearch extends IEntity {
	
    @Id
    @Column(length=200)
    private String id;
    private RelateProjValObj mainProj;//來源相關(guān)件
    @Lob
    @Type(type="org.hibernate.type.TextType")
    private String content;//檢索內(nèi)容
    @Column(length=100)
    private String contentType;//檢索類型
    @Column(length=100)
    private Date lastUpdateDate;//最后更新時間
    
    
    public String getId() {
        return id;
    }
    public String getContent() {
        return content;
    }
    public String getContentType() {
        return contentType;
    }
    public RelateProjValObj getMainProj() {
        return mainProj;
    }
    public Date getLastUpdateDate() {
		return lastUpdateDate;
	}
	
	
	public FullTextSearch() {
    }
    public FullTextSearch(RelateProjValObj mainProj, String contentType,
    		String content, Date lastUpdateDate) {
        this.id = mainProj.getProjKey()+"_"+contentType;
        this.mainProj = mainProj;
        this.content = content;
        this.contentType = contentType;
        this.lastUpdateDate = lastUpdateDate;
        if(this.lastUpdateDate==null){
            this.lastUpdateDate = new Date();
        }
    }

}

存儲數(shù)據(jù)格式

基于數(shù)據(jù)庫的全文檢索實現(xiàn),項目,數(shù)據(jù)庫,全文檢索
基于數(shù)據(jù)庫的全文檢索實現(xiàn),項目,數(shù)據(jù)庫,全文檢索

查詢

sql大致就是這樣的邏輯

select tv.id from tv_cmp_dw_query tv join tv_fulltext_search tvs on tv.id = tvs.proj_id where tvs.contet_type in () and conent like '%測試%'

事件處理機制請看另一篇文章
自定義事件處理機制文章來源地址http://www.zghlxwxcb.cn/news/detail-838720.html

到了這里,關(guān)于基于數(shù)據(jù)庫的全文檢索實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 實現(xiàn)全文檢索的方法

    實現(xiàn)網(wǎng)站全文檢索功能,可以采取多種方法,從簡單的基于數(shù)據(jù)庫的搜索到使用專門的全文檢索系統(tǒng)。以下是一些常見的實現(xiàn)全文檢索的方法: 1. **數(shù)據(jù)庫全文索引**: ? ?如果你的網(wǎng)站后端使用的是關(guān)系型數(shù)據(jù)庫(如MySQL),大多數(shù)數(shù)據(jù)庫管理系統(tǒng)都提供了全文索引的功能。

    2024年04月26日
    瀏覽(19)
  • Mysql 簡單實現(xiàn)全文檢索(FULLTEXT)

    版本支持 MySQL 5.6 以前的版本,只有 MyISAM 存儲引擎支持全文索引; MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存儲引擎均支持全文索引; 只有字段的數(shù)據(jù)類型為 char、varchar、text 及其系列才可以建全文索引。 按順序操做: 1.修改數(shù)據(jù)庫配置 etc/my.cnf 文件 [mysqld] 下面加入 ngram_token_s

    2024年02月09日
    瀏覽(23)
  • MySQL使用全文檢索實現(xiàn)模糊搜索

    創(chuàng)建全文檢索有兩種方式 方式一: 方法二: in boolean mode(布爾模式): 可以為檢索的字符串增加操作符,且不會像自然語言一樣自動拆詞查詢并集(除非手動空格隔開) 全文檢索模糊查詢使用全文索引來提高搜索效率,可以快速查詢大數(shù)據(jù)量中的模糊匹配結(jié)果。而LIKE模糊查

    2024年02月15日
    瀏覽(19)
  • ElasticSearch 實現(xiàn)分詞全文檢索 - SpringBoot 完整實現(xiàn) Demo

    ElasticSearch 實現(xiàn)分詞全文檢索 - SpringBoot 完整實現(xiàn) Demo

    需求 做一個類似百度的全文搜索功能 搜素自動補全(suggest) 分詞全文搜索 所用的技術(shù)如下: ElasticSearch Kibana 管理界面 IK Analysis 分詞器 SpringBoot 實現(xiàn)流程 可以通過 Canal 對 MySQL binlog 進行數(shù)據(jù)同步,或者 flink 或者 SpringBoot 直接往ES里添加數(shù)據(jù) 當(dāng)前以 SpringBoot 直接代碼同

    2024年02月03日
    瀏覽(25)
  • SpringBoot封裝Elasticsearch搜索引擎實現(xiàn)全文檢索

    注:本文實現(xiàn)了Java對Elasticseach的分頁檢索/不分頁檢索的封裝 ES就不用過多介紹了,直接上代碼: 創(chuàng)建Store類(與ES字段對應(yīng),用于接收ES數(shù)據(jù)) Elasticsearch全文檢索接口:不分頁檢索 Elasticsearch全文檢索接口:分頁檢索 本文實現(xiàn)了Java對Elasticsearch搜索引擎全文檢索的封裝 傳入

    2024年02月04日
    瀏覽(38)
  • Mysql 實現(xiàn)類似于 ElasticSearch 的全文檢索功能

    ? 一、前言 今天一個同事問我,如何使用 Mysql 實現(xiàn)類似于 ElasticSearch 的全文檢索功能,并且對檢索跑分?我當(dāng)時腦子里立馬產(chǎn)生了疑問?為啥不直接用es呢?簡單好用還賊快。但是聽他說,數(shù)據(jù)量不多,客戶給的時間非常有限,根本沒時間去搭建es,所以還是看一下

    2024年02月03日
    瀏覽(16)
  • MySQL全文檢索臨時代替ES實現(xiàn)快速搜索

    MySQL全文檢索臨時代替ES實現(xiàn)快速搜索

    引入 在MySQL 5.7.6之前,全文索引只支持英文全文索引,不支持中文全文索引,需要利用分詞器把中文段落預(yù)處理拆分成單詞,然后存入數(shù)據(jù)庫。 從MySQL 5.7.6開始,MySQL內(nèi)置了ngram全文解析器,用來支持中文、日文、韓文分詞。 全文索引只支持InnoDB和MyISAM引擎,支持的類型為C

    2024年02月07日
    瀏覽(31)
  • 【springboot微服務(wù)】Lucence實現(xiàn)Mysql全文檢索

    目錄 一、前言 1.1 常規(guī)調(diào)優(yōu)手段 1.1.1 加索引 1.1.2?代碼層優(yōu)化 1.1.3?減少關(guān)聯(lián)表查詢

    2023年04月12日
    瀏覽(24)
  • SpringBoot整合Lucene實現(xiàn)全文檢索【詳細步驟】【附源碼】

    SpringBoot整合Lucene實現(xiàn)全文檢索【詳細步驟】【附源碼】

    同樣,本文的出現(xiàn),也是我的個人網(wǎng)站笑小楓搭建的過程中產(chǎn)生的,作為一個技術(shù)博客為主的網(wǎng)站,Mysql的搜索已經(jīng)滿足不了我的野心了,于是,我便瞄上了全文檢索。最初,是打算直接使用比較熟悉的ES,但是考慮到部署ES額外的服務(wù)器資源開銷,最后選擇了Lucene,搭配IK分

    2024年02月04日
    瀏覽(20)
  • MySQL高級特性篇(3)-全文檢索的實現(xiàn)與優(yōu)化

    MySQL數(shù)據(jù)庫全文檢索是指對數(shù)據(jù)庫中的文本字段進行高效地搜索和匹配。在MySQL數(shù)據(jù)庫中,可以使用全文檢索來實現(xiàn)快速的文本搜索功能,并且可以通過一些優(yōu)化手段提高全文檢索的性能。 全文檢索是一種將搜索與自然語言處理技術(shù)結(jié)合起來的搜索方法。與傳統(tǒng)的基于

    2024年02月19日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包