美文网首页
iOS 海量数据本地实时搜索引擎

iOS 海量数据本地实时搜索引擎

作者: rain_ye | 来源:发表于2018-11-28 11:46 被阅读0次

    前言

    伴随着业务的迭代, 在数据量有大概四五万情况下, 需要实现实时搜索, 也就是在输入框输入时实时匹配搜索结果, 调用接口不太现实, 所以本地实现实时匹配. 类似于搜索通讯录联系人功能.
    数据结构一般是一个很大的数组, 例:

    [
      {
        "searchMainCondition": "10A片式保险丝",//搜索条件一
        "searchOtherCondition": "other"//搜索条件二
      },
      {
        "searchMainCondition": "10PK1045皮带",
        "searchOtherCondition": "other"
      },
      {
        "searchMainCondition": "ABS",
        "searchOtherCondition": "other"
      },
      {
        "searchMainCondition": "侧围窗内板(右)",
        "searchOtherCondition": "other"
      }
    ]
    

    实时搜索的过程可以根据searchMainCondition和searchOtherCondition等等其他条件同时进行模糊匹配

    中文转拼音及简单分词

    对原始数据做简单的处理, 对searchMainCondition进行全拼转为completeSpellingSearchterm, 由于待搜索completeSpellingSearchterm一般比较短, 只进行加空格达到简单的分词效果. 对searchMainCondition进行简拼转为logogramShorteningSearchterm,这样只需输入 'CWCNB' ---可以搜索到--- '侧围窗内板(右)'

    [
      {
        "searchMainCondition": "10A片式保险丝",//搜索条件一
        "searchOtherCondition": "other",//搜索条件二
        "completeSpellingSearchterm": "10APian Shi Bao Xian Si",//转为拼音
        "logogramShorteningSearchterm": ""//汉字首字母
      },
      {
        "searchMainCondition": "10PK1045皮带",
        "searchOtherCondition": "other",
        "completeSpellingSearchterm": "10PK1045Pi Dai",
        "logogramShorteningSearchterm": ""
      },
      {
        "searchMainCondition": "ABS",
        "searchOtherCondition": "other",
        "completeSpellingSearchterm": "ABS",
        "logogramShorteningSearchterm": "ABS"
      },
      {
        "searchMainCondition": "侧围窗内板(右)",
        "searchOtherCondition": "other",
        "completeSpellingSearchterm": "Ce Wei Chuang Nei Ban (You )",
        "logogramShorteningSearchterm": "CWCNB"
      }
    ]
    
    转化效果图.png
    汉字转拼音可以使用该框架中文转拼音, 核心代码块
    if ([ChineseInclude isIncludeChineseInString:dic[@"searchMainCondition"]]) {
                            NSString *completeSpellingSearchterm = [PinYinForObjc chineseConvertToPinYin:dic[@"searchMainCondition"]];
                            NSStrin *glogogramShorteningSearchterm = [PinYinForObjc chineseConvertToPinYinHead:dic[@"searchMainCondition"]];
                        }
    

    实时搜索引擎PermissiveResearch

    这时用到一个容错模糊搜索引擎PermissiveResearch可以下载修改后的版本PermissiveResearchModified

    1. 导入PermissiveResearchModified类库
    2. PermissiveAlignementMethods.c Identity and Type 更改为Objective-C Source
    3. 设置代理
    <UITextFieldDelegate, PermissiveResearchDatasource, PermissiveResearchDelegate>
    
    [[PermissiveResearchDatabase sharedDatabase] setDatasource:self];
    [[PermissiveResearchDatabase sharedDatabase] setDelegate:self];
    
    1. 文本输入发生变化时我们开始实现文本实时检索
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
         [self epcsGetSearchTermString:textField.text];
    }
    
    1. PermissiveResearchDatasource加载搜索源
    #pragma mark - PermissiveResearchDatasource
    
    - (void)rebuildDatabase
    {
         NSArray *dataArr = [self epcsGetSearchTermDataArr];
         [[PermissiveResearchDatabase sharedDatabase] addObjects:dataArr forKeyPaths:@[@"completeSpellingSearchterm"]];//根据转为拼音后的关键词搜索
    }
    
    - (NSArray *)epcsGetSearchTermDataArr
    {
         NSArray *sandboxpath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
         NSString *filePath = [[sandboxpath objectAtIndex:0] stringByAppendingPathComponent:@"epcsGetSearchTerm.plist"];
         NSArray *arrMain = [NSArray arrayWithContentsOfFile:filePath];
         return arrMain;
    }
    
    1. PermissiveResearchDelegate
    #pragma mark - PermissiveResearchDelegate
    
    -(void)epcsGetSearchTermString:(NSString *)searchedString
    {
         searchedKeywordsString = [[NSString alloc] initWithString:searchedString];//缓存中文搜索词
         if ([ChineseInclude isIncludeChineseInString:searchedString]) {
              searchedString = [PinYinForObjc chineseConvertToPinYin:searchedString];
         }
         [[PermissiveResearchDatabase sharedDatabase] searchString:searchedString withOperation:ScoringOperationTypeExact];
    }
    
    -(void)searchCompletedWithResults:(NSArray *)results
    {
         NSMutableArray *resultArr = @[].mutableCopy;
         if (results && results.count > 0) {
              NSMutableArray *perfectMatchArr = @[].mutableCopy;
              NSMutableArray *prefixArr = @[].mutableCopy;
              NSMutableArray *otherMatchArr = @[].mutableCopy;
              for (int i = 0; i < results.count; i++) {
                   id obj = [results objectAtIndex:i];//results为PermissiveObject对象
                   if ([obj isKindOfClass:[PermissiveObject class]]) {
                        PermissiveObject *permissiveObj = (PermissiveObject *)obj;
                        NSDictionary *dict = [permissiveObj refencedObject];
                        NSString *dicCurrentSearchterm = dict[@"searchterm"];
                        if ([dicCurrentSearchterm isEqualToString:searchedKeywordsString]) {
                             [perfectMatchArr addSafeObject:dict];//和搜索词完全匹配的
                        } else if ([dicCurrentSearchterm hasPrefix:searchedKeywordsString]) {
                             [prefixArr addSafeObject:dict];//以搜索词开头的
                        } else {
                             [otherMatchArr addSafeObject:dict];
                        }
                   }
              }
              //调整搜索结果顺序
              [resultArr addObjectsFromSafeArray:perfectMatchArr];
              [resultArr addObjectsFromSafeArray:prefixArr];
              [resultArr addObjectsFromSafeArray:otherMatchArr];
         }
         matchedSubDataArr = resultArr;
         //刷新数据
    }
    
    1. 清空数据源
    - (void)viewDidDisappear:(BOOL)animated
    {
         [super viewDidDisappear:animated];
         [[PermissiveResearchDatabase sharedDatabase] removeAllObjects];
    }
    

    相关文章

      网友评论

          本文标题:iOS 海量数据本地实时搜索引擎

          本文链接:https://www.haomeiwen.com/subject/riorqqtx.html