private static SearchResult InternalSearch(List <T> list, List <Bitap <T> > tokenSearchers, Bitap <T> fullSearcher, FuseOptions <T> options) { var resultMap = new Dictionary <int, AnalyzeResult>(); var results = new List <AnalyzeResult>(); var output = new AnalyzeOutput { resultMap = resultMap, results = results, tokenSearchers = tokenSearchers, fullSearcher = fullSearcher }; if (list[0] is string) { for (var i = 0; i < list.Count; i++) { Analyze(new AnalyzeOpts { key = "", value = (list[i] as string), record = i, index = i }, output, options); } return(new SearchResult { weights = null, results = results }); } var weights = new Dictionary <string, float>(); for (var i = 0; i < list.Count; i++) { var item = list[i]; for (var j = 0; j < options.keys.Count; j++) { var key = options.keys[j]; var weight = (1f - key.weight); if (weight == 0f) { weight = 1f; } weights[key.getter.Method.Name] = weight; Analyze(new AnalyzeOpts { key = key.getter.Method.Name, value = key.getter.Invoke(item), record = item, index = i }, output, options); } } return(new SearchResult { weights = weights, results = results }); }
private static void Analyze(AnalyzeOpts opts, AnalyzeOutput output, FuseOptions <T> options) { if (opts.value == null) { return; } var exists = false; var averageScore = -1f; var numTextMatches = 0; if (opts.value is string) { var mainSearchResult = output.fullSearcher.Search((string)opts.value); if (options.tokenize) { var words = options.tokenSeparator.Split((string)opts.value); var scores = new List <float>(); for (var i = 0; i < output.tokenSearchers.Count; i++) { var tokenSearcher = output.tokenSearchers[i]; var hasMatchInText = false; for (var j = 0; j < words.Length; j++) { var word = words[j]; var tokenSearchResult = tokenSearcher.Search(word); if (tokenSearchResult.isMatch) { exists = true; hasMatchInText = true; scores.Add(tokenSearchResult.score); } else { if (!options.matchAllTokens) { scores.Add(1f); } } } if (hasMatchInText) { numTextMatches += 1; } } averageScore = scores[0]; var scoresLen = scores.Count; for (var i = 1; i < scoresLen; i++) { averageScore += scores[i]; } averageScore = averageScore / scoresLen; } var finalScore = mainSearchResult.score; if (averageScore > -1f) { finalScore = (finalScore + averageScore) / 2f; } var checkTextMatches = (options.tokenize && options.matchAllTokens) ? numTextMatches >= output.tokenSearchers.Count : true; if ((exists || mainSearchResult.isMatch) && checkTextMatches) { if (output.resultMap.ContainsKey(opts.index)) { output.resultMap[opts.index].output.Add(new AnalyzeMatch { key = opts.key, arrayIndex = opts.arrayIndex, value = (string)opts.value, score = finalScore, matchedIndices = mainSearchResult.matchedIndices }); } else { output.resultMap[opts.index] = new AnalyzeResult { item = opts.record, output = new List <AnalyzeMatch> { new AnalyzeMatch { key = opts.key, arrayIndex = opts.arrayIndex, value = (string)opts.value, score = finalScore, matchedIndices = mainSearchResult.matchedIndices } } }; output.results.Add(output.resultMap[opts.index]); } } } else if (opts.value is List <string> ) { var list = (List <string>)opts.value; for (var i = 0; i < list.Count; i++) { Analyze(new AnalyzeOpts { key = opts.key, arrayIndex = i, value = list[i], record = opts.record, index = opts.index }, output, options); } } }
private SearchResult InternalSearch(List <Bitap <T> > tokenSearchers, Bitap <T> fullSearcher) { var resultMap = new Dictionary <int, AnalyzeResult>(); var results = new List <AnalyzeResult>(); var output = new AnalyzeOutput { resultMap = resultMap, results = results, tokenSearchers = tokenSearchers, fullSearcher = fullSearcher }; if (_list[0] is string) { for (var i = 0; i < _list.Count; i++) { Analyze(new AnalyzeOpts { key = "", value = (_list[i] as string), record = i, index = i }, output); } return(new SearchResult { weights = null, results = results }); } var weights = new Dictionary <string, float>(); for (var i = 0; i < _list.Count; i++) { var item = _list[i]; for (var j = 0; j < _options.keys.Count; j++) { var key = _options.keys[j]; var weight = (1f - key.weight); if (weight == 0f) { weight = 1f; } weights[key.name] = weight; Analyze(new AnalyzeOpts { key = key.name, value = _options.getFn(item, key.name), record = item, index = i }, output); } } return(new SearchResult { weights = weights, results = results }); }