多语言APP跨语言搜索实现咨询:支持同义词/缩写搜索
多语言APP搜索功能实现需求
我正在开发一款支持多语言的APP,希望搜索功能能无视内容语言返回全部匹配结果,例如搜索“cat”时同时显示含法语“chat”的内容;还需支持按缩写或同义词搜索,请问该如何实现?
以下是我的搜索功能代码:
class Search extends StatefulWidget { const Search({Key? key}) : super(key: key); @override State<Search> createState() => _SearchState(); } class _SearchState extends State<Search> { final TextEditingController _searchController = TextEditingController(); bool _readOnly = false; @override void initState() { BlocProvider.of<resultCubit>(context) .getresult(film: filmEntity(id: widget.film.id)); super.initState(); _searchController.addListener(() { setState(() {}); }); } @override void dispose() { _searchController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector(onTap: () { FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } }, child: Scaffold( body: BlocBuilder<resultCubit, resultState>( builder: (context, filmState) { if (filmState is resultLoaded) { List<filmEntity> result = filmState.films .where((film) => film.name!.contains( _searchController.text) || film.type!.contains( _searchController.text)) .toList(); return CustomScrollView( slivers: <Widget>[ SliverPadding( sliver: SliverAppBar( floating: true, snap: true, automaticallyImplyLeading: false, elevation: 0, title: TextFormFieldCustom( readOnly: _readOnly, controller: _searchController, hintText: 'Search ...', ), ), ), result.isNotEmpty ? SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return FilmTile( film: result[index], ); }, childCount: result.length, ), ) : const SliverEmptyWidget(), ], ); } else { return const Scaffold( body: Center(child: CircularProgressIndicator())); } }), )); } }
实现方案
1. 构建词汇映射表
先创建两个映射字典,分别处理跨语言匹配和同义词/缩写匹配:
// 跨语言词汇映射(键为基准词,值为对应其他语言的词汇) final Map<String, List<String>> crossLangMap = { 'cat': ['chat', 'gato', 'Katze'], 'dog': ['chien', 'perro', 'Hund'], // 根据业务需求扩展更多词汇 }; // 同义词/缩写映射 final Map<String, List<String>> synonymMap = { 'movie': ['film', 'flick'], 'tv': ['television', 'series'], 'info': ['information'], // 扩展更多同义词/缩写 };
2. 改造搜索匹配逻辑
替换原代码中where的过滤逻辑,实现多维度匹配:
List<filmEntity> result = filmState.films.where((film) { String query = _searchController.text.trim().toLowerCase(); if (query.isEmpty) return true; // 收集所有需要匹配的关键词集合 Set<String> matchTerms = {query}; // 添加跨语言匹配词 if (crossLangMap.containsKey(query)) { matchTerms.addAll(crossLangMap[query]!.map((term) => term.toLowerCase())); } // 添加同义词/缩写匹配词 if (synonymMap.containsKey(query)) { matchTerms.addAll(synonymMap[query]!.map((term) => term.toLowerCase())); } // 统一转为小写避免大小写敏感 String filmName = film.name?.toLowerCase() ?? ''; String filmType = film.type?.toLowerCase() ?? ''; // 检查名称或类型是否包含任意匹配词 return matchTerms.any((term) => filmName.contains(term) || filmType.contains(term)); }).toList();
3. 优化方向
- 预处理数据:如果数据量较大,在加载
filmEntity时就把name和type转为小写存储,减少搜索时的重复转换操作。 - 动态维护映射表:将映射表存为本地配置文件或接入远程配置,后续更新词汇无需修改代码重新打包。
- 模糊匹配增强:若需要处理拼写错误,可引入
string_similarity这类库,计算文本相似度来扩展匹配范围。
内容的提问来源于stack exchange,提问作者Laddybug Little
相关产品推荐
相关产品推荐

