func (s *ConjunctionQueryScorer) Score(constituents []*search.DocumentMatch) *search.DocumentMatch { rv := search.DocumentMatch{ ID: constituents[0].ID, } var sum float64 var childrenExplanations []*search.Explanation if s.explain { childrenExplanations = make([]*search.Explanation, len(constituents)) } locations := []search.FieldTermLocationMap{} for i, docMatch := range constituents { sum += docMatch.Score if s.explain { childrenExplanations[i] = docMatch.Expl } if docMatch.Locations != nil { locations = append(locations, docMatch.Locations) } } rv.Score = sum if s.explain { rv.Expl = &search.Explanation{Value: sum, Message: "sum of:", Children: childrenExplanations} } if len(locations) == 1 { rv.Locations = locations[0] } else if len(locations) > 1 { rv.Locations = search.MergeLocations(locations) } return &rv }
func (s *DisjunctionQueryScorer) Score(constituents []*search.DocumentMatch, countMatch, countTotal int) *search.DocumentMatch { rv := search.DocumentMatch{ ID: constituents[0].ID, } var sum float64 var childrenExplanations []*search.Explanation if s.explain { childrenExplanations = make([]*search.Explanation, len(constituents)) } locations := []search.FieldTermLocationMap{} for i, docMatch := range constituents { sum += docMatch.Score if s.explain { childrenExplanations[i] = docMatch.Expl } if docMatch.Locations != nil { locations = append(locations, docMatch.Locations) } } var rawExpl *search.Explanation if s.explain { rawExpl = &search.Explanation{Value: sum, Message: "sum of:", Children: childrenExplanations} } coord := float64(countMatch) / float64(countTotal) rv.Score = sum * coord if s.explain { ce := make([]*search.Explanation, 2) ce[0] = rawExpl ce[1] = &search.Explanation{Value: coord, Message: fmt.Sprintf("coord(%d/%d)", countMatch, countTotal)} rv.Expl = &search.Explanation{Value: rv.Score, Message: "product of:", Children: ce} } if len(locations) == 1 { rv.Locations = locations[0] } else if len(locations) > 1 { rv.Locations = search.MergeLocations(locations) } return &rv }
func (s *PhraseSearcher) Next() (*search.DocumentMatch, error) { if !s.initialized { err := s.initSearchers() if err != nil { return nil, err } } var rv *search.DocumentMatch for s.currMust != nil { rvftlm := make(search.FieldTermLocationMap, 0) freq := 0 firstTerm := s.terms[0] for field, termLocMap := range s.currMust.Locations { rvtlm := make(search.TermLocationMap, 0) locations, ok := termLocMap[firstTerm] if ok { OUTER: for _, location := range locations { crvtlm := make(search.TermLocationMap, 0) INNER: for i := 0; i < len(s.terms); i++ { nextTerm := s.terms[i] if nextTerm != "" { // look through all these term locations // to try and find the correct offsets nextLocations, ok := termLocMap[nextTerm] if ok { for _, nextLocation := range nextLocations { if nextLocation.Pos == location.Pos+float64(i) && nextLocation.SameArrayElement(location) { // found a location match for this term crvtlm.AddLocation(nextTerm, nextLocation) continue INNER } } // if we got here we didn't find a location match for this term continue OUTER } else { continue OUTER } } } // if we got here all the terms matched freq++ search.MergeTermLocationMaps(rvtlm, crvtlm) rvftlm[field] = rvtlm } } } if freq > 0 { // return match rv = s.currMust rv.Locations = rvftlm err := s.advanceNextMust() if err != nil { return nil, err } return rv, nil } err := s.advanceNextMust() if err != nil { return nil, err } } return nil, nil }
func (s *TermQueryScorer) Score(termMatch *index.TermFieldDoc) *search.DocumentMatch { var scoreExplanation *search.Explanation // need to compute score var tf float64 if termMatch.Freq < MaxSqrtCache { tf = SqrtCache[int(termMatch.Freq)] } else { tf = math.Sqrt(float64(termMatch.Freq)) } score := tf * termMatch.Norm * s.idf if s.explain { childrenExplanations := make([]*search.Explanation, 3) childrenExplanations[0] = &search.Explanation{ Value: tf, Message: fmt.Sprintf("tf(termFreq(%s:%s)=%d", s.queryField, string(s.queryTerm), termMatch.Freq), } childrenExplanations[1] = &search.Explanation{ Value: termMatch.Norm, Message: fmt.Sprintf("fieldNorm(field=%s, doc=%s)", s.queryField, termMatch.ID), } childrenExplanations[2] = s.idfExplanation scoreExplanation = &search.Explanation{ Value: score, Message: fmt.Sprintf("fieldWeight(%s:%s in %s), product of:", s.queryField, string(s.queryTerm), termMatch.ID), Children: childrenExplanations, } } // if the query weight isn't 1, multiply if s.queryWeight != 1.0 { score = score * s.queryWeight if s.explain { childExplanations := make([]*search.Explanation, 2) childExplanations[0] = s.queryWeightExplanation childExplanations[1] = scoreExplanation scoreExplanation = &search.Explanation{ Value: score, Message: fmt.Sprintf("weight(%s:%s^%f in %s), product of:", s.queryField, string(s.queryTerm), s.queryBoost, termMatch.ID), Children: childExplanations, } } } rv := search.DocumentMatch{ ID: termMatch.ID, Score: score, } if s.explain { rv.Expl = scoreExplanation } if termMatch.Vectors != nil && len(termMatch.Vectors) > 0 { rv.Locations = make(search.FieldTermLocationMap) for _, v := range termMatch.Vectors { tlm := rv.Locations[v.Field] if tlm == nil { tlm = make(search.TermLocationMap) } loc := search.Location{ Pos: float64(v.Pos), Start: float64(v.Start), End: float64(v.End), } if len(v.ArrayPositions) > 0 { loc.ArrayPositions = make([]float64, len(v.ArrayPositions)) for i, ap := range v.ArrayPositions { loc.ArrayPositions[i] = float64(ap) } } locations := tlm[s.queryTerm] if locations == nil { locations = make(search.Locations, 1) locations[0] = &loc } else { locations = append(locations, &loc) } tlm[s.queryTerm] = locations rv.Locations[v.Field] = tlm } } return &rv }