snapshot of https://github.com/blevesearch/bleve.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
Coverage / coverage (push) Failing after 6s
Tests / test (1.24.x, ubuntu-latest) (push) Failing after 42s
Tests / test (1.26.x, ubuntu-latest) (push) Failing after 38s
Tests / test (1.25.x, ubuntu-latest) (push) Failing after 35s
Tests / test (1.25.x, windows-latest) (push) Has been cancelled
Tests / test (1.26.x, macos-latest) (push) Has been cancelled
Tests / test (1.26.x, windows-latest) (push) Has been cancelled
Tests / test (1.24.x, macos-latest) (push) Has been cancelled
Tests / test (1.24.x, windows-latest) (push) Has been cancelled
Tests / test (1.25.x, macos-latest) (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-15 22:27:16 +05:00
commit f8d3d9f0cf
797 changed files with 159570 additions and 0 deletions

116
cmd/bleve/cmd/bulk.go Normal file
View File

@@ -0,0 +1,116 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"bufio"
"encoding/json"
"fmt"
"math/rand"
"os"
"github.com/spf13/cobra"
)
var batchSize int
// bulkCmd represents the bulk command
var bulkCmd = &cobra.Command{
Use: "bulk [index path] [data paths ...]",
Short: "bulk loads from newline delimited JSON files",
Long: `The bulk command will perform batch loading of documents in one or more newline delimited JSON files.`,
Annotations: map[string]string{
canMutateBleveIndex: "true",
},
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("must specify at least one path")
}
i := 0
batch := idx.NewBatch()
for _, file := range args[1:] {
file, err := os.Open(file)
if err != nil {
return err
}
fmt.Printf("Indexing: %s\n", file.Name())
r := bufio.NewReader(file)
for {
if i%batchSize == 0 {
fmt.Printf("Indexing batch (%d docs)...\n", i)
err := idx.Batch(batch)
if err != nil {
return err
}
batch = idx.NewBatch()
}
b, _ := r.ReadBytes('\n')
if len(b) == 0 {
break
}
var doc interface{} = b
var err error
if parseJSON {
err = json.Unmarshal(b, &doc)
if err != nil {
return fmt.Errorf("error parsing JSON: %v", err)
}
}
docID := randomString(5)
err = batch.Index(docID, doc)
if err != nil {
return err
}
i++
}
err = idx.Batch(batch)
if err != nil {
return err
}
err = file.Close()
if err != nil {
return err
}
}
return nil
},
}
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func randomString(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
func init() {
RootCmd.AddCommand(bulkCmd)
bulkCmd.Flags().IntVarP(&batchSize, "batch", "b", 1000, "Batch size for loading.")
bulkCmd.Flags().BoolVarP(&parseJSON, "json", "j", true, "Parse the contents as JSON.")
}

131
cmd/bleve/cmd/check.go Normal file
View File

@@ -0,0 +1,131 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"log"
"github.com/blevesearch/bleve/v2"
"github.com/spf13/cobra"
)
var checkFieldName string
var checkCount int
// checkCmd represents the check command
var checkCmd = &cobra.Command{
Use: "check [index path]",
Short: "checks the contents of the index",
Long: `The check command will perform consistency checks on the index.`,
RunE: func(cmd *cobra.Command, args []string) error {
var fieldNames []string
var err error
if checkFieldName == "" {
fieldNames, err = idx.Fields()
if err != nil {
return err
}
} else {
fieldNames = []string{checkFieldName}
}
fmt.Printf("checking fields: %v\n", fieldNames)
totalProblems := 0
for _, fieldName := range fieldNames {
fmt.Printf("checking field: '%s'\n", fieldName)
problems, err := checkField(idx, fieldName)
if err != nil {
log.Fatal(err)
}
totalProblems += problems
}
if totalProblems != 0 {
return fmt.Errorf("found %d total problems\n", totalProblems)
}
return nil
},
}
func checkField(index bleve.Index, fieldName string) (int, error) {
termDictionary, err := getDictionary(index, fieldName)
if err != nil {
return 0, err
}
fmt.Printf("field contains %d terms\n", len(termDictionary))
numTested := 0
numProblems := 0
for term, count := range termDictionary {
fmt.Printf("checked %d terms\r", numTested)
if checkCount > 0 && numTested >= checkCount {
break
}
tq := bleve.NewTermQuery(term)
tq.SetField(fieldName)
req := bleve.NewSearchRequest(tq)
req.Size = 0
res, err := index.Search(req)
if err != nil {
return 0, err
}
if res.Total != count {
fmt.Printf("unexpected mismatch for term '%s', dictionary %d, search hits %d\n", term, count, res.Total)
numProblems++
}
numTested++
}
fmt.Printf("done checking %d terms, found %d problems\n", numTested, numProblems)
return numProblems, nil
}
func getDictionary(index bleve.Index, field string) (map[string]uint64, error) {
rv := make(map[string]uint64)
i, err := index.Advanced()
if err != nil {
log.Fatal(err)
}
r, err := i.Reader()
if err != nil {
log.Fatal(err)
}
d, err := r.FieldDict(field)
if err != nil {
log.Fatal(err)
}
de, err := d.Next()
for err == nil && de != nil {
rv[de.Term] = de.Count
de, err = d.Next()
}
if err != nil {
return nil, err
}
return rv, nil
}
func init() {
RootCmd.AddCommand(checkCmd)
checkCmd.Flags().StringVarP(&checkFieldName, "field", "f", "", "Restrict check to the specified field name.")
checkCmd.Flags().IntVarP(&checkCount, "count", "c", 100, "Check this many terms.")
}

40
cmd/bleve/cmd/count.go Normal file
View File

@@ -0,0 +1,40 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// countCmd represents the count command
var countCmd = &cobra.Command{
Use: "count [index path]",
Short: "counts the number documents in the index",
Long: `The count command will count the number of documents in the index.`,
RunE: func(cmd *cobra.Command, args []string) error {
count, err := idx.DocCount()
if err != nil {
return fmt.Errorf("error counting docs in index: %v", err)
}
fmt.Printf("%d\n", count)
return nil
},
}
func init() {
RootCmd.AddCommand(countCmd)
}

81
cmd/bleve/cmd/create.go Normal file
View File

@@ -0,0 +1,81 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"encoding/json"
"fmt"
"os"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/mapping"
"github.com/spf13/cobra"
)
var mappingPath, indexType, storeType string
// createCmd represents the create command
var createCmd = &cobra.Command{
Use: "create [index path]",
Short: "creates a new index",
Long: `The create command will create a new empty index.`,
Annotations: map[string]string{
canMutateBleveIndex: "true",
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// override RootCmd version which opens existing index
if len(args) < 1 {
return fmt.Errorf("must specify path to index")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
var mapping mapping.IndexMapping
var err error
mapping, err = buildMapping()
if err != nil {
return fmt.Errorf("error building mapping: %v", err)
}
idx, err = bleve.NewUsing(args[0], mapping, indexType, storeType, nil)
if err != nil {
return fmt.Errorf("error creating index: %v", err)
}
// the inherited Post action will close the index
return nil
},
}
func buildMapping() (mapping.IndexMapping, error) {
mapping := mapping.NewIndexMapping()
if mappingPath != "" {
mappingBytes, err := os.ReadFile(mappingPath)
if err != nil {
return nil, err
}
err = json.Unmarshal(mappingBytes, &mapping)
if err != nil {
return nil, err
}
}
return mapping, nil
}
func init() {
RootCmd.AddCommand(createCmd)
createCmd.Flags().StringVarP(&mappingPath, "mapping", "m", "", "Path to a file containing a JSON representation of an index mapping to use.")
createCmd.Flags().StringVarP(&storeType, "store", "s", bleve.Config.DefaultKVStore, "The bleve storage type to use.")
createCmd.Flags().StringVarP(&indexType, "index", "i", bleve.Config.DefaultIndexType, "The bleve index type to use.")
}

View File

@@ -0,0 +1,60 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// dictionaryCmd represents the dictionary command
var dictionaryCmd = &cobra.Command{
Use: "dictionary [index path] [field name]",
Short: "prints the term dictionary for the specified field in the index",
Long: `The dictionary command will print the term dictionary for the specified field.`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("must specify field")
}
i, err := idx.Advanced()
if err != nil {
return fmt.Errorf("error getting index: %v", err)
}
r, err := i.Reader()
if err != nil {
return fmt.Errorf("error getting index reader: %v", err)
}
d, err := r.FieldDict(args[1])
if err != nil {
return fmt.Errorf("error getting field dictionary: %v", err)
}
de, err := d.Next()
for err == nil && de != nil {
fmt.Printf("%s - %d\n", de.Term, de.Count)
de, err = d.Next()
}
if err != nil {
return fmt.Errorf("error iterating dictionary: %v", err)
}
return nil
},
}
func init() {
RootCmd.AddCommand(dictionaryCmd)
}

61
cmd/bleve/cmd/dump.go Normal file
View File

@@ -0,0 +1,61 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"github.com/blevesearch/bleve/v2/index/upsidedown"
"github.com/spf13/cobra"
)
var docID string
// dumpCmd represents the dump command
var dumpCmd = &cobra.Command{
Use: "dump [index path]",
Short: "dumps the contents of the index",
Long: `The dump command will dump (possibly a section of) the index.`,
RunE: func(cmd *cobra.Command, args []string) error {
i, err := idx.Advanced()
if err != nil {
return fmt.Errorf("error getting index: %v", err)
}
r, err := i.Reader()
if err != nil {
return fmt.Errorf("error getting index reader: %v", err)
}
upsideDownReader, ok := r.(*upsidedown.IndexReader)
if !ok {
return fmt.Errorf("dump is only supported by index type upsidedown")
}
dumpChan := upsideDownReader.DumpAll()
for rowOrErr := range dumpChan {
switch rowOrErr := rowOrErr.(type) {
case error:
return fmt.Errorf("error dumping: %v", rowOrErr)
case upsidedown.UpsideDownCouchRow:
fmt.Printf("%v\n", rowOrErr)
fmt.Printf("Key: % -100x\nValue: % -100x\n\n", rowOrErr.Key(), rowOrErr.Value())
}
}
return nil
},
}
func init() {
RootCmd.AddCommand(dumpCmd)
}

63
cmd/bleve/cmd/dumpDoc.go Normal file
View File

@@ -0,0 +1,63 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"github.com/blevesearch/bleve/v2/index/upsidedown"
"github.com/spf13/cobra"
)
// dumpDocCmd represents the dumpDoc command
var dumpDocCmd = &cobra.Command{
Use: "doc [index path] [doc id]",
Short: "dump only the rows relating to this doc ID",
Long: `The doc sub-command of dump will only dump the rows relating to this doc ID.`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("must specify docid")
}
i, err := idx.Advanced()
if err != nil {
return fmt.Errorf("error getting index: %v", err)
}
r, err := i.Reader()
if err != nil {
return fmt.Errorf("error getting index reader: %v", err)
}
upsideDownReader, ok := r.(*upsidedown.IndexReader)
if !ok {
return fmt.Errorf("dump doc is only supported by index type upsidedown")
}
dumpChan := upsideDownReader.DumpDoc(args[1])
for rowOrErr := range dumpChan {
switch rowOrErr := rowOrErr.(type) {
case error:
return fmt.Errorf("error dumping: %v", rowOrErr)
case upsidedown.UpsideDownCouchRow:
fmt.Printf("%v\n", rowOrErr)
fmt.Printf("Key: % -100x\nValue: % -100x\n\n", rowOrErr.Key(), rowOrErr.Value())
}
}
return nil
},
}
func init() {
dumpCmd.AddCommand(dumpDocCmd)
}

View File

@@ -0,0 +1,59 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"github.com/blevesearch/bleve/v2/index/upsidedown"
"github.com/spf13/cobra"
)
// dumpFieldsCmd represents the dumpFields command
var dumpFieldsCmd = &cobra.Command{
Use: "fields [index path]",
Short: "dump only the field rows",
Long: `The fields sub-command of dump will only dump the field rows.`,
RunE: func(cmd *cobra.Command, args []string) error {
i, err := idx.Advanced()
if err != nil {
return fmt.Errorf("error getting index: %v", err)
}
r, err := i.Reader()
if err != nil {
return fmt.Errorf("error getting index reader: %v", err)
}
upsideDownReader, ok := r.(*upsidedown.IndexReader)
if !ok {
return fmt.Errorf("dump fields is only supported by index type upsidedown")
}
dumpChan := upsideDownReader.DumpFields()
for rowOrErr := range dumpChan {
switch rowOrErr := rowOrErr.(type) {
case error:
return fmt.Errorf("error dumping: %v", rowOrErr)
case upsidedown.UpsideDownCouchRow:
fmt.Printf("%v\n", rowOrErr)
fmt.Printf("Key: % -100x\nValue: % -100x\n\n", rowOrErr.Key(), rowOrErr.Value())
}
}
return nil
},
}
func init() {
dumpCmd.AddCommand(dumpFieldsCmd)
}

50
cmd/bleve/cmd/fields.go Normal file
View File

@@ -0,0 +1,50 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// fieldsCmd represents the fields command
var fieldsCmd = &cobra.Command{
Use: "fields [index path]",
Short: "lists the fields in this index",
Long: `The fields command will list the fields used in this index.`,
RunE: func(cmd *cobra.Command, args []string) error {
i, err := idx.Advanced()
if err != nil {
return fmt.Errorf("error getting index: %v", err)
}
r, err := i.Reader()
if err != nil {
return fmt.Errorf("error getting index reader: %v", err)
}
fields, err := r.Fields()
if err != nil {
return fmt.Errorf("error getting fields: %v", err)
}
for i, field := range fields {
fmt.Printf("%d - %s\n", i, field)
}
return nil
},
}
func init() {
RootCmd.AddCommand(fieldsCmd)
}

116
cmd/bleve/cmd/index.go Normal file
View File

@@ -0,0 +1,116 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"github.com/spf13/cobra"
)
var keepDir, keepExt, parseJSON bool
// indexCmd represents the index command
var indexCmd = &cobra.Command{
Use: "index [index path] [data paths ...]",
Short: "adds the files to the index",
Long: `The index command adds the specified files to the index.`,
Annotations: map[string]string{
canMutateBleveIndex: "true",
},
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("must specify at least one path")
}
for file := range handleArgs(args[1:]) {
var doc interface{}
// index the files
docID := file.filename
if !keepDir {
_, docID = filepath.Split(docID)
}
if !keepExt {
ext := filepath.Ext(docID)
docID = docID[0 : len(docID)-len(ext)]
}
doc = file.contents
var err error
if parseJSON {
err = json.Unmarshal(file.contents, &doc)
if err != nil {
return fmt.Errorf("error parsing JSON: %v", err)
}
}
fmt.Printf("Indexing: %s\n", docID)
err = idx.Index(docID, doc)
if err != nil {
return fmt.Errorf("error indexing: %v", err)
}
}
return nil
},
}
type file struct {
filename string
contents []byte
}
func handleArgs(args []string) chan file {
rv := make(chan file)
go getAllFiles(args, rv)
return rv
}
func getAllFiles(args []string, rv chan file) {
for _, arg := range args {
arg = filepath.Clean(arg)
err := filepath.Walk(arg, func(path string, finfo os.FileInfo, err error) error {
if err != nil {
log.Print(err)
return err
}
if finfo.IsDir() {
return nil
}
bytes, err := os.ReadFile(path)
if err != nil {
log.Fatal(err)
}
rv <- file{
filename: filepath.Base(path),
contents: bytes,
}
return nil
})
if err != nil {
log.Fatal(err)
}
}
close(rv)
}
func init() {
RootCmd.AddCommand(indexCmd)
indexCmd.Flags().BoolVarP(&keepDir, "keepDir", "d", false, "Keep the directory in the document id.")
indexCmd.Flags().BoolVarP(&keepExt, "keepExt", "x", false, "Keep the extension in the document id.")
indexCmd.Flags().BoolVarP(&parseJSON, "json", "j", true, "Parse the contents as JSON.")
}

42
cmd/bleve/cmd/mapping.go Normal file
View File

@@ -0,0 +1,42 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"encoding/json"
"fmt"
"log"
"github.com/spf13/cobra"
)
// mappingCmd represents the mapping command
var mappingCmd = &cobra.Command{
Use: "mapping [index path]",
Short: "prints the mapping used for this index",
Long: `The mapping command prints a JSON representation of the mapping used for this index.`,
Run: func(cmd *cobra.Command, args []string) {
mapping := idx.Mapping()
jsonBytes, err := json.MarshalIndent(mapping, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", jsonBytes)
},
}
func init() {
RootCmd.AddCommand(mappingCmd)
}

101
cmd/bleve/cmd/query.go Normal file
View File

@@ -0,0 +1,101 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"strings"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/search/query"
"github.com/spf13/cobra"
)
var limit, skip, repeat int
var explain, highlight, fields bool
var qtype, qfield, sortby string
// queryCmd represents the query command
var queryCmd = &cobra.Command{
Use: "query [index path] [query]",
Short: "queries the index",
Long: `The query command will execute a query against the index.`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("must specify query")
}
query := buildQuery(args)
for i := 0; i < repeat; i++ {
req := bleve.NewSearchRequestOptions(query, limit, skip, explain)
if highlight {
req.Highlight = bleve.NewHighlightWithStyle("ansi")
}
if fields {
req.Fields = []string{"*"}
}
if sortby != "" {
if strings.Contains(sortby, ",") {
req.SortBy(strings.Split(sortby, ","))
} else {
req.SortBy([]string{sortby})
}
}
res, err := idx.Search(req)
if err != nil {
return fmt.Errorf("error running query: %v", err)
}
fmt.Println(res)
}
return nil
},
}
func buildQuery(args []string) query.Query {
var q query.Query
switch qtype {
case "prefix":
pquery := bleve.NewPrefixQuery(strings.Join(args[1:], " "))
if qfield != "" {
pquery.SetField(qfield)
}
q = pquery
case "term":
pquery := bleve.NewTermQuery(strings.Join(args[1:], " "))
if qfield != "" {
pquery.SetField(qfield)
}
q = pquery
default:
// build a search with the provided parameters
queryString := strings.Join(args[1:], " ")
q = bleve.NewQueryStringQuery(queryString)
}
return q
}
func init() {
RootCmd.AddCommand(queryCmd)
queryCmd.Flags().IntVarP(&repeat, "repeat", "r", 1, "Repeat the query this many times.")
queryCmd.Flags().IntVarP(&limit, "limit", "l", 10, "Limit number of results returned.")
queryCmd.Flags().IntVarP(&skip, "skip", "s", 0, "Skip the first N results.")
queryCmd.Flags().BoolVarP(&explain, "explain", "x", false, "Explain the result scoring.")
queryCmd.Flags().BoolVar(&highlight, "highlight", true, "Highlight matching text in results.")
queryCmd.Flags().BoolVar(&fields, "fields", false, "Load stored fields.")
queryCmd.Flags().StringVarP(&qtype, "type", "t", "query_string", "Type of query to run.")
queryCmd.Flags().StringVarP(&qfield, "field", "f", "", "Restrict query to field, not applicable to query_string queries.")
queryCmd.Flags().StringVarP(&sortby, "sort-by", "b", "", "Sort by field.")
}

88
cmd/bleve/cmd/registry.go Normal file
View File

@@ -0,0 +1,88 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"sort"
"github.com/blevesearch/bleve/v2/registry"
"github.com/spf13/cobra"
)
// registryCmd represents the registry command
var registryCmd = &cobra.Command{
Use: "registry",
Short: "registry lists the bleve components compiled into this executable",
Long: `The registry command will list all of the bleve components compiled into this executable.`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// override to do nothing
return nil
},
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
// override to do nothing
return nil
},
Run: func(cmd *cobra.Command, args []string) {
types, instances := registry.CharFilterTypesAndInstances()
printType("Char Filter", types, instances)
types, instances = registry.TokenizerTypesAndInstances()
printType("Tokenizer", types, instances)
types, instances = registry.TokenMapTypesAndInstances()
printType("Token Map", types, instances)
types, instances = registry.TokenFilterTypesAndInstances()
printType("Token Filter", types, instances)
types, instances = registry.AnalyzerTypesAndInstances()
printType("Analyzer", types, instances)
types, instances = registry.DateTimeParserTypesAndInstances()
printType("Date Time Parser", types, instances)
types, instances = registry.KVStoreTypesAndInstances()
printType("KV Store", types, instances)
types, instances = registry.FragmentFormatterTypesAndInstances()
printType("Fragment Formatter", types, instances)
types, instances = registry.FragmenterTypesAndInstances()
printType("Fragmenter", types, instances)
types, instances = registry.HighlighterTypesAndInstances()
printType("Highlighter", types, instances)
},
}
func printType(label string, types, instances []string) {
sort.Strings(types)
sort.Strings(instances)
fmt.Printf("%s Types:\n", label)
for _, name := range types {
fmt.Printf("\t%s\n", name)
}
fmt.Println()
fmt.Printf("%s Instances:\n", label)
for _, name := range instances {
fmt.Printf("\t%s\n", name)
}
fmt.Println()
}
func init() {
RootCmd.AddCommand(registryCmd)
}

93
cmd/bleve/cmd/root.go Normal file
View File

@@ -0,0 +1,93 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"os"
"strconv"
"github.com/blevesearch/bleve/v2"
"github.com/spf13/cobra"
)
var cfgFile string
var idx bleve.Index
// DefaultOpenReadOnly allows some distributions of this command to default
// to always opening the index read-only
var DefaultOpenReadOnly = false
const canMutateBleveIndex = "canMutateBleveIndex"
// CanMutateBleveIndex returns true if the command is capable
// of mutating the bleve index, or false if its operation is
// read-only
func CanMutateBleveIndex(c *cobra.Command) bool {
for k, v := range c.Annotations {
if k == canMutateBleveIndex {
if b, err := strconv.ParseBool(v); err == nil && b {
return true
}
}
}
return false
}
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "bleve",
Short: "command-line tool to interact with a bleve index",
Long: `Bleve is a command-line tool to interact with a bleve index.`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if cmd.Use == "bash" || cmd.Use == "zsh" || cmd.Use == "fish" || cmd.Use == "powershell" {
// Not applicable to cobra's completion subcommands
return nil
}
if len(args) < 1 {
return fmt.Errorf("must specify path to index")
}
runtimeConfig := map[string]interface{}{
"read_only": DefaultOpenReadOnly,
}
var err error
idx, err = bleve.OpenUsing(args[0], runtimeConfig)
if err != nil {
return fmt.Errorf("error opening bleve index: %v", err)
}
return nil
},
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
if cmd.Use == "bash" || cmd.Use == "zsh" || cmd.Use == "fish" || cmd.Use == "powershell" {
// Not applicable to cobra's completion subcommands
return nil
}
err := idx.Close()
if err != nil {
return fmt.Errorf("error closing bleve index: %v", err)
}
return nil
},
}
// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(-1)
}
}

25
cmd/bleve/cmd/scorch.go Normal file
View File

@@ -0,0 +1,25 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"github.com/blevesearch/bleve/v2/cmd/bleve/cmd/scorch"
)
// make scorch command-line tool a bleve sub-command
func init() {
RootCmd.AddCommand(scorch.RootCmd)
}

View File

@@ -0,0 +1,59 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package scorch
import (
"fmt"
"strconv"
"github.com/blevesearch/bleve/v2/index/scorch/mergeplan"
"github.com/spf13/cobra"
)
// asciiCmd represents the ascii command
var asciiCmd = &cobra.Command{
Use: "ascii",
Short: "ascii prints an ascii representation of the segments in a snapshot",
Long: `The ascii command prints an ascii representation of the segments in a given snapshot.`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("snapshot epoch required")
} else if len(args) < 3 {
snapshotEpoch, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
return err
}
snapshot, err := index.LoadSnapshot(snapshotEpoch)
if err != nil {
return err
}
segments := snapshot.Segments()
var mergePlanSegments []mergeplan.Segment
for _, v := range segments {
mergePlanSegments = append(mergePlanSegments, v)
}
str := mergeplan.ToBarChart(args[1], 25, mergePlanSegments, nil)
fmt.Printf("%s\n", str)
}
return nil
},
}
func init() {
RootCmd.AddCommand(asciiCmd)
}

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package scorch
import (
"fmt"
"strconv"
"github.com/spf13/cobra"
)
// deletedCmd represents the deleted command
var deletedCmd = &cobra.Command{
Use: "deleted",
Short: "deleted prints the deleted bitmap for segments in the index snapshot",
Long: `The delete command prints the deleted bitmap for segments in the index snapshot.`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("snapshot epoch required")
} else if len(args) < 3 {
snapshotEpoch, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
return err
}
snapshot, err := index.LoadSnapshot(snapshotEpoch)
if err != nil {
return err
}
segments := snapshot.Segments()
for i, segmentSnap := range segments {
deleted := segmentSnap.Deleted()
fmt.Printf("%d %v\n", i, deleted)
}
}
return nil
},
}
func init() {
RootCmd.AddCommand(deletedCmd)
}

View File

@@ -0,0 +1,59 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package scorch
import (
"fmt"
"github.com/spf13/cobra"
)
// dictCmd represents the dict command
var infoCmd = &cobra.Command{
Use: "info",
Short: "info prints basic info about the index",
Long: `The info command prints basic info about the index.`,
RunE: func(cmd *cobra.Command, args []string) error {
reader, err := index.Reader()
if err != nil {
return err
}
count, err := reader.DocCount()
if err != nil {
return err
}
fmt.Printf("doc count: %d\n", count)
// var numSnapshots int
// var rootSnapshot uint64
// index.VisitBoltSnapshots(func(snapshotEpoch uint64) error {
// if rootSnapshot == 0 {
// rootSnapshot = snapshotEpoch
// }
// numSnapshots++
// return nil
// })
// fmt.Printf("has %d snapshot(s), root: %d\n", numSnapshots, rootSnapshot)
return nil
},
}
func init() {
RootCmd.AddCommand(infoCmd)
}

View File

@@ -0,0 +1,61 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package scorch
import (
"fmt"
"strconv"
"github.com/spf13/cobra"
)
var ascii bool
// internalCmd represents the internal command
var internalCmd = &cobra.Command{
Use: "internal",
Short: "internal prints the internal k/v pairs in a snapshot",
Long: `The internal command prints the internal k/v pairs in a snapshot.`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("snapshot epoch required")
} else if len(args) < 3 {
snapshotEpoch, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
return err
}
snapshot, err := index.LoadSnapshot(snapshotEpoch)
if err != nil {
return err
}
internal := snapshot.Internal()
for k, v := range internal {
if ascii {
fmt.Printf("%s %s\n", k, string(v))
} else {
fmt.Printf("%x %x\n", k, v)
}
}
}
return nil
},
}
func init() {
RootCmd.AddCommand(internalCmd)
internalCmd.Flags().BoolVarP(&ascii, "ascii", "a", false, "print key/value in ascii")
}

View File

@@ -0,0 +1,70 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package scorch
import (
"fmt"
"os"
"github.com/blevesearch/bleve/v2/index/scorch"
"github.com/spf13/cobra"
)
var index *scorch.Scorch
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "scorch",
Short: "command-line tool to interact with a scorch index",
Long: `Scorch is a command-line tool to interact with a scorch index.`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("must specify path to scorch index")
}
readOnly := true
config := map[string]interface{}{
"read_only": readOnly,
"path": args[0],
}
idx, err := scorch.NewScorch(scorch.Name, config, nil)
if err != nil {
return err
}
err = idx.Open()
if err != nil {
return fmt.Errorf("error opening: %v", err)
}
index = idx.(*scorch.Scorch)
return nil
},
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
return nil
},
}
// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(-1)
}
}

View File

@@ -0,0 +1,64 @@
// Copyright (c) 2017 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package scorch
import (
"fmt"
"strconv"
seg "github.com/blevesearch/scorch_segment_api/v2"
"github.com/spf13/cobra"
)
// snapshotCmd represents the snapshot command
var snapshotCmd = &cobra.Command{
Use: "snapshot",
Short: "info prints details about the snapshots in the index",
Long: `The snapshot command prints details about the snapshots in the index.`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
snapshotEpochs, err := index.RootBoltSnapshotEpochs()
if err != nil {
return err
}
for _, snapshotEpoch := range snapshotEpochs {
fmt.Printf("snapshot epoch: %d\n", snapshotEpoch)
}
} else if len(args) < 3 {
snapshotEpoch, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
return err
}
snapshot, err := index.LoadSnapshot(snapshotEpoch)
if err != nil {
return err
}
segments := snapshot.Segments()
for i, segmentSnap := range segments {
segment := segmentSnap.Segment()
if segment, ok := segment.(seg.PersistedSegment); ok {
fmt.Printf("%d %s\n", i, segment.Path())
}
}
}
return nil
},
}
func init() {
RootCmd.AddCommand(snapshotCmd)
}

45
cmd/bleve/gendocs.go Normal file
View File

@@ -0,0 +1,45 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build ignore
// +build ignore
package main
import (
"fmt"
"github.com/blevesearch/bleve/v2/cmd/bleve/cmd"
"github.com/spf13/cobra/doc"
)
// you can generate markdown docs by running
//
// $ go run gendocs.go
//
// this also requires doc sub-package of cobra
// which is not kept in this repo
// you can acquire it by running
//
// $ gvt restore
func main() {
cmd.RootCmd.DisableAutoGenTag = true
identity := func(s string) string {
return fmt.Sprintf(`{{< relref "docs/%s" >}}`, s)
}
emptyStr := func(s string) string { return "" }
doc.GenMarkdownTreeCustom(cmd.RootCmd, "./", emptyStr, identity)
}

26
cmd/bleve/main.go Normal file
View File

@@ -0,0 +1,26 @@
// Copyright © 2016 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"github.com/blevesearch/bleve/v2/cmd/bleve/cmd"
// to support standard set of build tags
_ "github.com/blevesearch/bleve/v2/config"
)
func main() {
cmd.Execute()
}