github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/search/explanation.go (about)

     1  package search
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  )
     7  
     8  // search/Explanation.java
     9  
    10  type Explanation interface {
    11  	// Indicate whether or not this Explanation models a good match.
    12  	// By default, an Explanation represents a "match" if the value is positive.
    13  	IsMatch() bool
    14  	// The value assigned to this explanation node.
    15  	Value() float32
    16  }
    17  
    18  type ExplanationSPI interface {
    19  	Explanation
    20  	// A short one line summary which should contian all high level information
    21  	// about this Explanation, without the Details.
    22  	Summary() string
    23  	Details() []Explanation
    24  }
    25  
    26  /* Expert: Describes the score computation for document and query. */
    27  type ExplanationImpl struct {
    28  	spi         ExplanationSPI
    29  	value       float32       // the value of this node
    30  	description string        // what it represents
    31  	details     []Explanation // sub-explanations
    32  }
    33  
    34  func newExplanation(value float32, description string) *ExplanationImpl {
    35  	ans := &ExplanationImpl{value: value, description: description}
    36  	ans.spi = ans
    37  	return ans
    38  }
    39  
    40  func (exp *ExplanationImpl) IsMatch() bool       { return exp.value > 0.0 }
    41  func (exp *ExplanationImpl) Value() float32      { return exp.value }
    42  func (exp *ExplanationImpl) Description() string { return exp.description }
    43  
    44  func (exp *ExplanationImpl) Summary() string {
    45  	return fmt.Sprintf("%v = %v", exp.value, exp.description)
    46  }
    47  
    48  // The sub-nodes of this explanation node.
    49  func (exp *ExplanationImpl) Details() []Explanation {
    50  	return exp.details
    51  }
    52  
    53  // Adds a sub-node to this explanation node
    54  func (exp *ExplanationImpl) addDetail(detail Explanation) {
    55  	exp.details = append(exp.details, detail)
    56  }
    57  
    58  // Render an explanation as text.
    59  func (exp *ExplanationImpl) String() string {
    60  	return explanationToString(exp.spi, 0)
    61  }
    62  
    63  func explanationToString(exp ExplanationSPI, depth int) string {
    64  	assert(depth <= 1000) // potential dead loop
    65  	var buf bytes.Buffer
    66  	for i := 0; i < depth; i++ {
    67  		buf.WriteString("  ")
    68  	}
    69  	buf.WriteString(exp.Summary())
    70  	buf.WriteString("\n")
    71  
    72  	for _, v := range exp.Details() {
    73  		buf.WriteString(explanationToString(v.(ExplanationSPI), depth+1))
    74  	}
    75  
    76  	return buf.String()
    77  }
    78  
    79  // search/ComplexExplanation.java
    80  
    81  /*
    82  Expert: Describes the score computation for the doucment and query,
    83  and can distinguish a match independent of a postive value.
    84  */
    85  type ComplexExplanation struct {
    86  	*ExplanationImpl
    87  	match interface{}
    88  }
    89  
    90  func newEmptyComplexExplanation() *ComplexExplanation {
    91  	ans := new(ComplexExplanation)
    92  	ans.ExplanationImpl = new(ExplanationImpl)
    93  	ans.spi = ans
    94  	return ans
    95  }
    96  
    97  func newComplexExplanation(match bool, value float32, desc string) *ComplexExplanation {
    98  	ans := new(ComplexExplanation)
    99  	ans.ExplanationImpl = newExplanation(value, desc)
   100  	ans.spi = ans
   101  	ans.match = match
   102  	return ans
   103  }
   104  
   105  /*
   106  Indicates whether or not this Explanation models a good match.
   107  
   108  If the match status is explicitly set (i.e.: not nil) this method
   109  uses it; otherwise it defers to the superclass.
   110  */
   111  func (e *ComplexExplanation) IsMatch() bool {
   112  	return e.match != nil && e.match.(bool) || e.match == nil && e.ExplanationImpl.IsMatch()
   113  }
   114  
   115  func (e *ComplexExplanation) Summary() string {
   116  	if e.match == nil {
   117  		return e.ExplanationImpl.Summary()
   118  	}
   119  	return fmt.Sprintf("%v = %v %v", e.Value(),
   120  		map[bool]string{true: "(MATCH)", false: "(NON_MATCH)"}[e.IsMatch()],
   121  		e.Description())
   122  }