search パッケージは、App Engine の検索サービス用のクライアントを提供します。
基本オペレーション
インデックスにはドキュメントが格納されます。インデックスは名前(人が読み取れる形式の ASCII 文字列)で識別されます。
インデックス内ではドキュメントに ID が関連付けられています。この ID も人が読み取れる形式の ASCII 文字列です。ドキュメントのコンテンツは、大文字と小文字を区別するフィールド名と値のマッピングです。フィールド値に有効なタイプは次のとおりです。
- string、
- search.Atom、
- search.HTML、
- time.Time(ミリ秒単位の精度で格納)、
- float64(-2,147,483,647~2,147,483,647 の範囲内の値)、
- appengine.GeoPoint。
インデックスの Get メソッドはドキュメントを読み込み、Put メソッドはドキュメントを保存します。ドキュメントのコンテンツは通常、構造体ポインタによって表されます。
コードの例:
type Doc struct { Author string Comment string Creation time.Time } index, err := search.Open("comments") if err != nil { return err } newID, err := index.Put(ctx, "", &Doc{ Author: "gopher", Comment: "the truth of the matter", Creation: time.Now(), }) if err != nil { return err }
1 つのドキュメントは ID で取得できます。格納先の構造体を Get に渡し、結果のドキュメントを格納します。
var doc Doc err := index.Get(ctx, id, &doc) if err != nil { return err }
ドキュメントの検索とリスティング
インデックスで複数のドキュメントを一度に取得する場合、Search と List の 2 つのメソッドがあります。
クエリのインデックスを検索すると、イテレータが返されます。package パッケージのイテレータと同様に、変換先の構造体を Next に渡し、次の結果をデコードします。イテレータがなくなると、Next は Done を返します。
for t := index.Search(ctx, "Comment:truth", nil); ; { var doc Doc id, err := t.Next(&doc) if err == search.Done { break } if err != nil { return err } fmt.Fprintf(w, "%s -> %#v\n", id, doc) }
Search は文字列クエリを使用して、返すドキュメントを決定します。1 単語のような簡単なクエリもあれば、複雑なクエリもあります。クエリ言語については、https://cloud.google.com/appengine/docs/standard/go/search/query_strings をご覧ください。
また、Search で SearchOptions 構造体を使用することもできます。この構造体を使用すると、結果の計算方法や取得方法をより柔軟に制御できます。
List を呼び出し、インデックス内のすべてのドキュメントに反復処理を行います。
for t := index.List(ctx, nil); ; { var doc Doc id, err := t.Next(&doc) if err == search.Done { break } if err != nil { return err } fmt.Fprintf(w, "%s -> %#v\n", id, doc) }
フィールドとファセット
ドキュメントのコンテンツは、さまざまな型で表現されます。これらは通常、構造体ポインタですが、FieldLoadSaver インターフェースを実装する任意の型で表すこともできます。FieldLoadSaver を使用すると、DocumentMetadata 型のドキュメントにメタデータを設定できます。構造体ポインタはより厳密に型指定され、使いやすいのに対して、FieldLoadSavers はより柔軟に使用できます。
ドキュメントのコンテンツは、フィールドとファセットの 2 つの方法で表現できます。
ドキュメントのコンテンツを提供する場合、一般的に使用されるのがフィールドです。フィールドには、異なる型のデータを格納でき、クエリ文字列を使用した検索で比較できます。
ファセットは、カテゴリ情報をドキュメントに追加する場合に使用します。ファセットの有効なタイプは search.Atom と float64 です。ファセットを使用すると、検索で一致したカテゴリの要約を検索結果に含めることができます。また、検索範囲を特定のカテゴリに限定することもできます。
デフォルトでは、構造体ポインタのすべての構造体フィールドはドキュメント フィールドとして使用されます。使用されるフィールド名は構造体と同じです(フィールド名は大文字で始まります)。構造体フィールドには search:"name,options"
タグを付けることもできます。名前は文字で始まり、単語のみで構成されている必要があります。"-" タグは、フィールドが無視されることを意味します。options が "facet" の場合、構造体フィールドはドキュメント ファセットとして使用されます。options が "" の場合、カンマは省略できます。これ以外に認識されるオプションはありません。
コードの例:
// A and B are renamed to a and b. // A, C and I are facets. // D's tag is equivalent to having no tag at all (E). // F and G are ignored entirely by the search package. // I has tag information for both the search and json packages. type TaggedStruct struct { A float64 `search:"a,facet"` B float64 `search:"b"` C float64 `search:",facet"` D float64 `search:""` E float64 F float64 `search:"-"` G float64 `search:"-,facet"` I float64 `search:",facet" json:"i"` }
FieldLoadSaver インターフェース
ドキュメントのコンテンツは、FieldLoadSaver インターフェースを実装する任意の型で表すこともできます。この型は、構造体ポインタにすることもできますが、必ずしもそうする必要はありません。search パッケージは、ドキュメントのコンテンツの読み込み時に Load を呼び出し、保存時に Save を呼び出します。フィールドのスライス以外に、Load と Save メソッドは DocumentMetadata 型を使用してドキュメントに関する追加情報(ランクや一連のファセット)を提供します。このインターフェースの使用例として、格納されていないフィールドの取得、フィールドの検証、文字列フィールドや HTML フィールドへの特定の言語の設定などが考えられます。
コードの例:
type CustomFieldsExample struct { // Item's title and which language it is in. Title string Lang string // Mass, in grams. Mass int } func (x *CustomFieldsExample) Load(fields []search.Field, meta *search.DocumentMetadata) error { // Load the title field, failing if any other field is found. for _, f := range fields { if f.Name != "title" { return fmt.Errorf("unknown field %q", f.Name) } s, ok := f.Value.(string) if !ok { return fmt.Errorf("unsupported type %T for field %q", f.Value, f.Name) } x.Title = s x.Lang = f.Language } // Load the mass facet, failing if any other facet is found. for _, f := range meta.Facets { if f.Name != "mass" { return fmt.Errorf("unknown facet %q", f.Name) } m, ok := f.Value.(float64) if !ok { return fmt.Errorf("unsupported type %T for facet %q", f.Value, f.Name) } x.Mass = int(m) } return nil } func (x *CustomFieldsExample) Save() ([]search.Field, *search.DocumentMetadata, error) { fields := []search.Field{ {Name: "title", Value: x.Title, Language: x.Lang}, } meta := &search.DocumentMetadata{ Facets: { {Name: "mass", Value: float64(x.Mass)}, }, } return fields, meta, nil }
変数
ErrInvalidDocumentType、ErrNoSuchDocument、ErrTooManyDocuments
var (
// ErrInvalidDocumentType is returned when methods like Put, Get or Next
// are passed a dst or src argument of invalid type.
ErrInvalidDocumentType = errors.New("search: invalid document type")
// ErrNoSuchDocument is returned when no document was found for a given ID.
ErrNoSuchDocument = errors.New("search: no such document")
// ErrTooManyDocuments is returned when the user passes too many documents to
// PutMulti or DeleteMulti.
ErrTooManyDocuments = fmt.Errorf("search: too many documents given to put or delete (max is %d)", maxDocumentsPerPutDelete)
)
Done
Done は、クエリのイテレーションが完了したときに返されます。
関数
func LoadStruct
LoadStruct は、f から dst までのフィールドを読み込みます。dst は構造体ポインタである必要があります。
Atom
type Atom string
Atom は、分割不可能な文字列としてコンテンツがインデックス化されているドキュメント フィールドです。
Cursor
type Cursor string
Cursor は、イテレータの位置を表します。
カーソルの文字列値はウェブセーフです。後で使用するために、保存して復元できます。
DocumentMetadata
type DocumentMetadata struct {
// Rank is an integer specifying the order the document will be returned in
// search results. If zero, the rank will be set to the number of seconds since
// 2011-01-01 00:00:00 UTC when being Put into an index.
Rank int
// Facets is the set of facets for this document.
Facets []Facet
}
DocumentMetadata は、特定のドキュメントに関する情報を格納する構造体です。
ErrFacetMismatch
ErrFacetMismatch は、フィールドが格納元と異なる型に読み込まれたとき、または格納先の構造体でフィールドが見つからないかエクスポートされないときに返されます。StructType は、Iterator.Next に渡される宛先引数によって参照される構造体の型です。
func (*ErrFacetMismatch) Error
func (e *ErrFacetMismatch) Error() string
ErrFieldMismatch
ErrFieldMismatch は、フィールドが格納元と異なる型に読み込まれたとき、または格納先の構造体でフィールドが見つからないかエクスポートされないときに返されます。
func (*ErrFieldMismatch) Error
func (e *ErrFieldMismatch) Error() string
Facet
type Facet struct {
// Name is the facet name. A valid facet name matches /[A-Za-z][A-Za-z0-9_]*/.
// A facet name cannot be longer than 500 characters.
Name string
// Value is the facet value.
//
// When being used in documents (for example, in
// DocumentMetadata.Facets), the valid types are:
// - search.Atom,
// - float64.
//
// When being used in SearchOptions.Refinements or being returned
// in FacetResult, the valid types are:
// - search.Atom,
// - search.Range.
Value interface{}
}
Facet は、ドキュメントにカテゴリ情報を追加するための名前と値のペアです。
FacetResult
type FacetResult struct {
Facet
// Count is the number of times this specific facet and value appeared in the
// matching documents.
Count int
}
FacetResult は、検索リクエストに一致するドキュメントで特定のファセットと値が出現する回数を表します。
FacetSearchOption
type FacetSearchOption interface {
// contains filtered or unexported methods
}
FacetSearchOption は、検索結果で返されるファセット情報を制御します。
func AutoFacetDiscovery
func AutoFacetDiscovery(facetLimit, valueLimit int) FacetSearchOption
AutoFacetDiscovery は、検索で自動ファセット検出を有効にする FacetSearchOption を返します。自動ファセット検出は、一致するドキュメントの集計で最も頻繁に出現するファセットを探します。
返されるファセットの最大数は facetLimit で制御します。ファセットごとの値の最大数も facetLimit で制御します。制限が 0 の場合、デフォルトの制限が使用されます。
func FacetDiscovery
func FacetDiscovery(name string, value ...interface{}) FacetSearchOption
FacetDiscovery は、検索結果で返すファセットを選択する FacetSearchOption を返します。デフォルトでは、ファセットで最も頻繁に発生する値が返されます。特定の Atoms または Ranges のリストを指定することもできます。
func FacetDocumentDepth
func FacetDocumentDepth(depth int) FacetSearchOption
FacetDocumentDepth は、ファセットの検索で評価するドキュメントの数を制御する FacetSearchOption を返します。
Field
type Field struct {
// Name is the field name. A valid field name matches /[A-Za-z][A-Za-z0-9_]*/.
Name string
// Value is the field value. The valid types are:
// - string,
// - search.Atom,
// - search.HTML,
// - time.Time (stored with millisecond precision),
// - float64,
// - GeoPoint.
Value interface{}
// Language is a two-letter ISO 639-1 code for the field's language,
// defaulting to "en" if nothing is specified. It may only be specified for
// fields of type string and search.HTML.
Language string
// Derived marks fields that were calculated as a result of a
// FieldExpression provided to Search. This field is ignored when saving a
// document.
Derived bool
}
Field は、名前と値のペアです。検索インデックスのドキュメントは、一連のフィールドとして読み込まれ、保存されます。
func SaveStruct
SaveStruct は、src のフィールドを Field のスライスとして返します。src は構造体ポインタである必要があります。
FieldExpression
type FieldExpression struct {
// Name is the name to use for the computed field.
Name string
// Expr is evaluated to provide a custom content snippet for each document.
// See https://cloud.google.com/appengine/docs/standard/go/search/options for
// the supported expression syntax.
Expr string
}
FieldExpression は、結果を評価するカスタム式を定義します。
FieldList
type FieldList []Field
FieldList は、FieldLoadSaver を実装するために []Field を変換します。
func (*FieldList) Load
func (l *FieldList) Load(f []Field, _ *DocumentMetadata) error
Load は、渡されたすべてのフィールドを l に読み込みます。*l は事前に空のスライスにリセットされません。
func (*FieldList) Save
func (l *FieldList) Save() ([]Field, *DocumentMetadata, error)
Save は l のすべてのフィールドをフィールドのスライスとして保存します。
FieldLoadSaver
type FieldLoadSaver interface {
Load([]Field, *DocumentMetadata) error
Save() ([]Field, *DocumentMetadata, error)
}
FieldLoadSaver は、追加のドキュメント メタデータを使用してフィールドのスライスの間で変換できます。
HTML
type HTML string
HTML は、コンテンツが HTML としてインデックス化されるドキュメント フィールドです。テキストノードのみがインデックス化されます。「foobar」は「foobar」として処理されます。
Index
type Index struct {
// contains filtered or unexported fields
}
Index は、ドキュメントのインデックスです。
func Open
Open は、指定された名前のインデックスを開きます。インデックスがまだ存在しない場合は作成します。
名前は人が読める ASCII 文字列です。空白文字を含めることはできません。また、! で始めることもできません。
func (*Index) Delete
Delete は、インデックスからドキュメントを削除します。
func (*Index) DeleteMulti
DeleteMulti は、インデックスから複数のドキュメントを削除します。
返されるエラーは appengine.MultiError のインスタンスである可能性があります。この場合、srcs と同じサイズになり、内部の個々のエラーは srcs のアイテムに対応します。
func (*Index) Get
Get は、指定された ID のドキュメントを dst に読み込みます。
ID は、人が読める ASCII 形式の文字列です。空にすることはできません。空白文字を含めることや、! で始めることもできません。
dst は、nil 以外の構造化ポインタにするか、FieldLoadSaver インターフェースを実装する必要があります。
ErrFieldMismatch は、フィールドが格納元と異なる型に読み込まれたとき、または格納先の構造体でフィールドが見つからないかエクスポートされないときに返されます。ErrFieldMismatch は、dst が構造体ポインタである場合にのみ返されます。このエラーが致命的か、回復可能か、無視できるかどうかは呼び出し側が判断します。
func (*Index) List
func (x *Index) List(c context.Context, opts *ListOptions) *Iterator
List は、インデックス内のすべてのドキュメントをリスティングします。ドキュメントは、ID の昇順で返されます。
func (*Index) Put
Put は、src をインデックスに保存します。id が空の場合、サービスによって新しい ID が割り当てられ、返されます。id が空でない場合、その ID の既存のインデックス エントリが置換されます。
ID は、人が読める ASCII 形式の文字列です。空白文字を含めることはできません。また、! で始めることもできません。
src は、nil 以外の構造体ポインタであるか、FieldLoadSaver インターフェースを実装する必要があります。
func (*Index) PutMulti
PutMulti は Put に似ていますが、複数のドキュメントを一度にインデックスに追加するために効率的です。
一度に最大 200 個のドキュメントを追加できます。さらに追加しようとすると、ErrTooManyDocuments が返されます。
ids は、空のスライス(追加されたドキュメントごとに新しい ID が割り当てられる)または srcs と同じサイズのスライスのいずれかです。
エラーは appengine.MultiError のインスタンスである可能性があります。この場合、srcs と同じサイズになり、内部の個々のエラーは srcs のアイテムに対応します。
func (*Index) Search
Search は、指定されたクエリのインデックスを検索します。
Iterator
type Iterator struct {
// contains filtered or unexported fields
}
Iterator は、クエリのインデックスの検索結果か、インデックスのリスティングの結果です。
func (*Iterator) Count
Count は、クエリに一致したドキュメント数の近似値を返します。Search によって返されたイテレータを呼び出す場合にのみ有効です。
func (*Iterator) Cursor
Cursor は、現在のドキュメント(Next の呼び出しで返された最新のドキュメント)に関連するカーソルを返します。
このカーソルを今後の Search の呼び出しで渡すと、現在のドキュメントの次のドキュメントから返されます。
func (*Iterator) Facets
func (t *Iterator) Facets() ([][]FacetResult, error)
Facets は、ファセットが SearchOptions でリクエストされた場合に検索結果で見つかったファセットを返します。
func (*Iterator) Next
Next は、次の結果の ID を返します。結果がない場合は、エラーとして Done が返されます。
dst は、nil 以外の構造化ポインタにするか、FieldLoadSaver インターフェースを実装するか、nil インターフェース値にする必要があります。nil 以外の dst が渡されると、インデックス化されたフィールドで更新されます。このイテレータが IDsOnly オプションで作成された場合は、dst が無視されます。
ListOptions
type ListOptions struct {
// StartID is the inclusive lower bound for the ID of the returned
// documents. The zero value means all documents will be returned.
StartID string
// Limit is the maximum number of documents to return. The zero value
// indicates no limit.
Limit int
// IDsOnly indicates that only document IDs should be returned for the list
// operation; no document fields are populated.
IDsOnly bool
}
ListOptions は、インデックスのドキュメントをリスティングするオプションです。nil*ListOptions を渡すと、デフォルト値を使用する場合と同じ結果になります。
Range
type Range struct {
Start, End float64
}
Range は、開始を含み、終了を含まない数値の範囲を表します。Start を math.Inf(-1) として指定すると、最小値がないことを示すことができます。同様に、End にも math.Inf(1) を指定できます。Start または End のいずれかは有限数にする必要があります。
func AtLeast
AtLeast は、min 以上の値に一致する Range を返します。
func LessThan
LessThan は、max 未満の値に一致する Range を返します。
Scorer
type Scorer interface {
// contains filtered or unexported methods
}
Scorer は、ドキュメント スコアの計算方法を定義します。
MatchScorer、RescoringMatchScorer
var (
// MatchScorer assigns a score based on term frequency in a document.
MatchScorer Scorer = enumScorer{pb.ScorerSpec_MATCH_SCORER}
// RescoringMatchScorer assigns a score based on the quality of the query
// match. It is similar to a MatchScorer but uses a more complex scoring
// algorithm based on match term frequency and other factors like field type.
// Please be aware that this algorithm is continually refined and can change
// over time without notice. This means that the ordering of search results
// that use this scorer can also change without notice.
RescoringMatchScorer Scorer = enumScorer{pb.ScorerSpec_RESCORING_MATCH_SCORER}
)
SearchOptions
type SearchOptions struct {
// Limit is the maximum number of documents to return. The zero value
// indicates no limit.
Limit int
// IDsOnly indicates that only document IDs should be returned for the search
// operation; no document fields are populated.
IDsOnly bool
// Sort controls the ordering of search results.
Sort *SortOptions
// Fields specifies which document fields to include in the results. If omitted,
// all document fields are returned. No more than 100 fields may be specified.
Fields []string
// Expressions specifies additional computed fields to add to each returned
// document.
Expressions []FieldExpression
// Facets controls what facet information is returned for these search results.
// If no options are specified, no facet results will be returned.
Facets []FacetSearchOption
// Refinements filters the returned documents by requiring them to contain facets
// with specific values. Refinements are applied in conjunction for facets with
// different names, and in disjunction otherwise.
Refinements []Facet
// Cursor causes the results to commence with the first document after
// the document associated with the cursor.
Cursor Cursor
// Offset specifies the number of documents to skip over before returning results.
// When specified, Cursor must be nil.
Offset int
// CountAccuracy specifies the maximum result count that can be expected to
// be accurate. If zero, the count accuracy defaults to 20.
CountAccuracy int
}
SearchOptions は、インデックス検索のオプションです。nil*SearchOptions を渡すと、デフォルト値を使用した場合と同じ結果になります。
SortExpression
type SortExpression struct {
// Expr is evaluated to provide a sorting value for each document.
// See https://cloud.google.com/appengine/docs/standard/go/search/options for
// the supported expression syntax.
Expr string
// Reverse causes the documents to be sorted in ascending order.
Reverse bool
// The default value to use when no field is present or the expresion
// cannot be calculated for a document. For text sorts, Default must
// be of type string; for numeric sorts, float64.
Default interface{}
}
SortExpression は、ドキュメントを並べ替えるための分割項目を定義します。
SortOptions
type SortOptions struct {
// Expressions is a slice of expressions representing a multi-dimensional
// sort.
Expressions []SortExpression
// Scorer, when specified, will cause the documents to be scored according to
// search term frequency.
Scorer Scorer
// Limit is the maximum number of objects to score and/or sort. Limit cannot
// be more than 10,000. The zero value indicates a default limit.
Limit int
}
SortOptions は、検索結果の順序とスコアを制御します。