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

27
test/integration.go Normal file
View File

@@ -0,0 +1,27 @@
// Copyright (c) 2014 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 test
import (
"github.com/blevesearch/bleve/v2"
)
type SearchTest struct {
Search *bleve.SearchRequest `json:"search"`
Result *bleve.SearchResult `json:"result"`
Comment string `json:"comment"`
}
type SearchTests []*SearchTest

279
test/integration_test.go Normal file
View File

@@ -0,0 +1,279 @@
// Copyright (c) 2014 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 test
import (
"encoding/json"
"flag"
"fmt"
"math"
"os"
"path/filepath"
"reflect"
"regexp"
"testing"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/mapping"
// allow choosing alternate kvstores
_ "github.com/blevesearch/bleve/v2/config"
)
var dataset = flag.String("dataset", "", "only test datasets matching this regex")
var onlynum = flag.Int("testnum", -1, "only run the test with this number")
var keepIndex = flag.Bool("keepIndex", false, "keep the index after testing")
var indexType = flag.String("indexType", bleve.Config.DefaultIndexType, "index type to build")
var kvType = flag.String("kvType", bleve.Config.DefaultKVStore, "kv store type to build")
var segType = flag.String("segType", "", "force scorch segment type")
var segVer = flag.Int("segVer", 0, "force scorch segment version")
func TestIntegration(t *testing.T) {
flag.Parse()
t.Logf("using index type %s and kv type %s", *indexType, *kvType)
if *segType != "" {
t.Logf("forcing segment type: %s", *segType)
}
if *segVer != 0 {
t.Logf("forcing segment version: %d", *segVer)
}
var err error
var datasetRegexp *regexp.Regexp
if *dataset != "" {
datasetRegexp, err = regexp.Compile(*dataset)
if err != nil {
t.Fatal(err)
}
}
entries, err := os.ReadDir("tests")
if err != nil {
t.Fatal(err)
}
for _, f := range entries {
if datasetRegexp != nil {
if !datasetRegexp.MatchString(f.Name()) {
continue
}
}
if f.IsDir() {
t.Logf("Running test: %s", f.Name())
runTestDir(t, "tests"+string(filepath.Separator)+f.Name(), f.Name())
}
}
}
func runTestDir(t *testing.T, dir, datasetName string) {
// read the mapping
mappingBytes, err := os.ReadFile(dir + string(filepath.Separator) + "mapping.json")
if err != nil {
t.Errorf("error reading mapping: %v", err)
return
}
var mapping mapping.IndexMappingImpl
err = json.Unmarshal(mappingBytes, &mapping)
if err != nil {
t.Errorf("error unmarshalling mapping: %v", err)
return
}
var index bleve.Index
var cleanup func()
// if there is a dir named 'data' open single index
_, err = os.Stat(dir + string(filepath.Separator) + "data")
if !os.IsNotExist(err) {
index, cleanup, err = loadDataSet(t, datasetName, mapping, dir+string(filepath.Separator)+"data")
if err != nil {
t.Errorf("error loading dataset: %v", err)
return
}
defer cleanup()
} else {
// if there is a dir named 'datasets' build alias over each index
_, err = os.Stat(dir + string(filepath.Separator) + "datasets")
if !os.IsNotExist(err) {
index, cleanup, err = loadDataSets(t, datasetName, mapping, dir+string(filepath.Separator)+"datasets")
if err != nil {
t.Errorf("error loading dataset: %v", err)
return
}
defer cleanup()
}
}
// read the searches
searchBytes, err := os.ReadFile(dir + string(filepath.Separator) + "searches.json")
if err != nil {
t.Errorf("error reading searches: %v", err)
return
}
var searches SearchTests
err = json.Unmarshal(searchBytes, &searches)
if err != nil {
t.Errorf("error unmarshalling searches: %v", err)
return
}
// run the searches
for testNum, search := range searches {
if *onlynum < 0 || (*onlynum > 0 && testNum == *onlynum) {
res, err := index.Search(search.Search)
if err != nil {
t.Errorf("error running search: %v", err)
}
if res.Total != search.Result.Total {
t.Errorf("test error - %s", search.Comment)
t.Errorf("test %d - expected total: %d got %d", testNum, search.Result.Total, res.Total)
continue
}
if len(res.Hits) != len(search.Result.Hits) {
t.Errorf("test error - %s", search.Comment)
t.Errorf("test %d - expected hits len: %d got %d", testNum, len(search.Result.Hits), len(res.Hits))
t.Errorf("got hits: %v", res.Hits)
continue
}
for hi, hit := range search.Result.Hits {
if hit.ID != res.Hits[hi].ID {
t.Errorf("test error - %s", search.Comment)
t.Errorf("test %d - expected hit %d to have ID %s got %s", testNum, hi, hit.ID, res.Hits[hi].ID)
}
if hit.Fields != nil {
if !reflect.DeepEqual(hit.Fields, res.Hits[hi].Fields) {
t.Errorf("test error - %s", search.Comment)
t.Errorf("test %d - expected hit %d to have fields %#v got %#v", testNum, hi, hit.Fields, res.Hits[hi].Fields)
}
}
if hit.Fragments != nil {
if !reflect.DeepEqual(hit.Fragments, res.Hits[hi].Fragments) {
t.Errorf("test error - %s", search.Comment)
t.Errorf("test %d - expected hit %d to have fragments %#v got %#v", testNum, hi, hit.Fragments, res.Hits[hi].Fragments)
}
}
if hit.Locations != nil {
if !reflect.DeepEqual(hit.Locations, res.Hits[hi].Locations) {
t.Errorf("test error - %s", search.Comment)
t.Errorf("test %d - expected hit %d to have locations %#v got %#v", testNum, hi, hit.Locations, res.Hits[hi].Locations)
}
}
// assert that none of the scores were NaN,+Inf,-Inf
if math.IsInf(res.Hits[hi].Score, 0) || math.IsNaN(res.Hits[hi].Score) {
t.Errorf("test error - %s", search.Comment)
t.Errorf("test %d - invalid score %f", testNum, res.Hits[hi].Score)
}
}
if search.Result.Facets != nil {
if !reflect.DeepEqual(search.Result.Facets, res.Facets) {
t.Errorf("test error - %s", search.Comment)
t.Errorf("test %d - expected facets: %#v got %#v", testNum, search.Result.Facets, res.Facets)
}
}
if _, ok := index.(bleve.IndexAlias); !ok {
// check that custom index name is in results
for _, hit := range res.Hits {
if hit.Index != datasetName {
t.Fatalf("expected name: %s, got: %s", datasetName, hit.Index)
}
}
}
}
}
}
func loadDataSet(t *testing.T, datasetName string, mapping mapping.IndexMappingImpl, path string) (bleve.Index, func(), error) {
idxPath := fmt.Sprintf("test-%s.bleve", datasetName)
cfg := map[string]interface{}{}
if *segType != "" {
cfg["forceSegmentType"] = *segType
}
if *segVer != 0 {
cfg["forceSegmentVersion"] = *segVer
}
index, err := bleve.NewUsing(idxPath, &mapping, *indexType, *kvType, cfg)
if err != nil {
return nil, nil, fmt.Errorf("error creating new index: %v", err)
}
// set a custom index name
index.SetName(datasetName)
// index data
entries, err := os.ReadDir(path)
if err != nil {
return nil, nil, fmt.Errorf("error reading data dir: %v", err)
}
for _, f := range entries {
fileBytes, err := os.ReadFile(path + string(filepath.Separator) + f.Name())
if err != nil {
return nil, nil, fmt.Errorf("error reading data file: %v", err)
}
var fileDoc interface{}
err = json.Unmarshal(fileBytes, &fileDoc)
if err != nil {
return nil, nil, fmt.Errorf("error parsing data file as json: %v", err)
}
filename := f.Name()
ext := filepath.Ext(filename)
id := filename[0 : len(filename)-len(ext)]
err = index.Index(id, fileDoc)
if err != nil {
return nil, nil, fmt.Errorf("error indexing data: %v", err)
}
}
cleanup := func() {
err := index.Close()
if err != nil {
t.Fatalf("error closing index: %v", err)
}
if !*keepIndex {
err := os.RemoveAll(idxPath)
if err != nil {
t.Fatalf("error removing index: %v", err)
}
}
}
return index, cleanup, nil
}
func loadDataSets(t *testing.T, datasetName string, mapping mapping.IndexMappingImpl, path string) (bleve.Index, func(), error) {
entries, err := os.ReadDir(path)
if err != nil {
return nil, nil, fmt.Errorf("error reading datasets dir: %v", err)
}
var cleanups []func()
alias := bleve.NewIndexAlias()
for _, f := range entries {
idx, idxCleanup, err := loadDataSet(t, f.Name(), mapping, path+string(filepath.Separator)+f.Name())
if err != nil {
return nil, nil, fmt.Errorf("error loading dataset: %v", err)
}
cleanups = append(cleanups, idxCleanup)
alias.Add(idx)
}
alias.SetName(datasetName)
cleanupAll := func() {
for _, cleanup := range cleanups {
cleanup()
}
}
return alias, cleanupAll, nil
}

272
test/ip_field_test.go Normal file
View File

@@ -0,0 +1,272 @@
// Copyright (c) 2021 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 test
import (
"net"
"testing"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/mapping"
)
type doc struct {
IP string `json:"ip"`
}
func createIdx(t *testing.T) bleve.Index {
ipIndexed := mapping.NewIPFieldMapping()
ipIndexed.Name = "ip"
lineMapping := bleve.NewDocumentStaticMapping()
lineMapping.AddFieldMappingsAt("ip", ipIndexed)
mapping := bleve.NewIndexMapping()
mapping.DefaultMapping = lineMapping
mapping.DefaultAnalyzer = "standard"
idx, err := bleve.NewMemOnly(mapping)
if err != nil {
t.Fatal(err)
}
return idx
}
func Test_ipv4CidrQuery(t *testing.T) {
idx := createIdx(t)
defer idx.Close()
err := idx.Index("id1", doc{"192.168.1.21"})
if err != nil {
t.Fatal(err)
}
reqStr := `192.168.1.0/24`
query := bleve.NewIPRangeQuery(reqStr)
query.FieldVal = "ip"
search := bleve.NewSearchRequest(query)
res, err := idx.Search(search)
if err != nil {
t.Fatal(err)
}
if res.Total != 1 {
t.Fatalf("failed to find %q, res -> %s", reqStr, res)
}
if res.Hits[0].ID != "id1" {
t.Fatalf("expected %q got %q", "id1", res.Hits[0].Index)
}
}
func Test_ipv6CidrQuery(t *testing.T) {
idx := createIdx(t)
defer idx.Close()
err := idx.Index("id1", doc{"2a00:23c8:7283:ff00:1fa8:2af6:9dec:6b19"})
if err != nil {
t.Fatal(err)
}
reqStr := `2a00:23c8:7283:ff00:1fa8:0:0:0/80`
query := bleve.NewIPRangeQuery(reqStr)
query.FieldVal = "ip"
search := bleve.NewSearchRequest(query)
res, err := idx.Search(search)
if err != nil {
t.Fatal(err)
}
if res.Total != 1 {
t.Fatalf("failed to find %q, res -> %s", reqStr, res)
}
if res.Hits[0].ID != "id1" {
t.Fatalf("expected %q got %q", "id1", res.Hits[0].Index)
}
}
func Test_MultiIPvr4CidrQuery(t *testing.T) {
idx := createIdx(t)
defer idx.Close()
err := idx.Index("id1", doc{"192.168.1.0"})
if err != nil {
t.Fatal(err)
}
err = idx.Index("id2", doc{"192.168.1.255"})
if err != nil {
t.Fatal(err)
}
err = idx.Index("id3", doc{"192.168.2.22"})
if err != nil {
t.Fatal(err)
}
reqStr := `192.168.1.0/24`
query := bleve.NewIPRangeQuery(reqStr)
query.FieldVal = "ip"
search := bleve.NewSearchRequest(query)
res, err := idx.Search(search)
if err != nil {
t.Fatal(err)
}
if res.Total != 2 {
t.Fatalf("failed to find %q, res -> %s", reqStr, res)
}
if res.Hits[0].ID != "id1" {
t.Fatalf("expected %q got %q", "id1", res.Hits[0].ID)
}
if res.Hits[1].ID != "id2" {
t.Fatalf("expected %q got %q", "id2", res.Hits[0].Index)
}
}
func Test_CidrQueryNonDivisibleBy8(t *testing.T) {
idx := createIdx(t)
defer idx.Close()
err := idx.Index("id1", doc{"192.168.1.1"})
if err != nil {
t.Fatal(err)
}
err = idx.Index("id2", doc{"192.168.1.2"})
if err != nil {
t.Fatal(err)
}
err = idx.Index("id3", doc{"192.168.2.5"})
if err != nil {
t.Fatal(err)
}
err = idx.Index("id4", doc{"192.168.2.6"})
if err != nil {
t.Fatal(err)
}
reqStr := `192.168.1.0/30`
query := bleve.NewIPRangeQuery(reqStr)
query.FieldVal = "ip"
search := bleve.NewSearchRequest(query)
res, err := idx.Search(search)
if err != nil {
t.Fatal(err)
}
if res.Total != 2 {
t.Fatalf("failed to find %q, res -> %s", reqStr, res)
}
if res.Hits[0].ID != "id1" {
t.Fatalf("expected %q got %q", "id1", res.Hits[0].ID)
}
if res.Hits[1].ID != "id2" {
t.Fatalf("expected %q got %q", "id2", res.Hits[0].Index)
}
}
func Test_simpleIPv4MatchQuery(t *testing.T) {
idx := createIdx(t)
defer idx.Close()
err := idx.Index("id1", doc{"192.168.1.21"})
if err != nil {
t.Fatal(err)
}
reqStr := `192.168.1.21`
query := bleve.NewIPRangeQuery(reqStr)
query.FieldVal = "ip"
search := bleve.NewSearchRequest(query)
res, err := idx.Search(search)
if err != nil {
t.Fatal(err)
}
if res.Total != 1 {
t.Fatalf("failed to find %q, res -> %s", reqStr, res)
}
if res.Hits[0].ID != "id1" {
t.Fatalf("expected %q got %q", "id1", res.Hits[0].Index)
}
}
func Test_ipv4LiteralData(t *testing.T) {
idx := createIdx(t)
defer idx.Close()
type stronglyTyped struct {
IP net.IP `json:"ip"`
}
err := idx.Index("id1", stronglyTyped{net.ParseIP("192.168.1.21")})
if err != nil {
t.Fatal(err)
}
reqStr := `192.168.1.0/24`
query := bleve.NewIPRangeQuery(reqStr)
query.FieldVal = "ip"
search := bleve.NewSearchRequest(query)
res, err := idx.Search(search)
if err != nil {
t.Fatal(err)
}
if res.Total != 1 {
t.Fatalf("failed to find %q, res -> %s", reqStr, res)
}
if res.Hits[0].ID != "id1" {
t.Fatalf("expected %q got %q", "id1", res.Hits[0].Index)
}
}
func Test_badIPFmt(t *testing.T) {
idx := createIdx(t)
defer idx.Close()
reqStr := `192.168.1.`
query := bleve.NewIPRangeQuery(reqStr)
query.FieldVal = "ip"
search := bleve.NewSearchRequest(query)
_, err := idx.Search(search)
if err == nil {
t.Errorf("%q is not a valid IP", reqStr)
}
}
func Test_badCIDRFmt(t *testing.T) {
idx := createIdx(t)
defer idx.Close()
reqStr := `/`
query := bleve.NewIPRangeQuery(reqStr)
query.FieldVal = "ip"
err := query.Validate()
if err == nil {
t.Errorf("%q is not a valid CIDR", reqStr)
}
search := bleve.NewSearchRequest(query)
_, err = idx.Search(search)
if err == nil {
t.Errorf("%q is not a valid CIDR", reqStr)
}
}

View File

@@ -0,0 +1,3 @@
{
"name": "a"
}

View File

@@ -0,0 +1,3 @@
{
"name": "c"
}

View File

@@ -0,0 +1,3 @@
{
"name": "b"
}

View File

@@ -0,0 +1,3 @@
{
"name": "d"
}

View File

@@ -0,0 +1,3 @@
{
"default_analyzer": "keyword"
}

View File

@@ -0,0 +1,76 @@
[
{
"comment": "match all across shards",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"match_all": {}
}
},
"result": {
"total_hits": 4,
"hits": [
{
"id": "a"
},
{
"id": "b"
},
{
"id": "c"
},
{
"id": "d"
}
]
}
},
{
"comment": "search after b (page 2 when size=2)",
"search": {
"from": 0,
"size": 2,
"sort": ["name"],
"search_after": ["b"],
"query": {
"match_all": {}
}
},
"result": {
"total_hits": 4,
"hits": [
{
"id": "c"
},
{
"id": "d"
}
]
}
},
{
"comment": "search before c (page 1 when size=2)",
"search": {
"from": 0,
"size": 2,
"sort": ["name"],
"search_before": ["c"],
"query": {
"match_all": {}
}
},
"result": {
"total_hits": 4,
"hits": [
{
"id": "a"
},
{
"id": "b"
}
]
}
}
]

View File

@@ -0,0 +1,7 @@
{
"id": "a",
"name": "marty",
"age": 19,
"title": "mista",
"tags": ["gopher", "belieber"]
}

View File

@@ -0,0 +1,7 @@
{
"id": "b",
"name": "steve has <a> long & complicated name",
"age": 27,
"birthday": "2001-09-09T01:46:40Z",
"title": "missess"
}

View File

@@ -0,0 +1,7 @@
{
"id": "c",
"name": "bob walks home",
"age": 64,
"birthday": "2014-05-13T16:53:20Z",
"title": "masta"
}

View File

@@ -0,0 +1,7 @@
{
"id": "d",
"name": "bobbleheaded wings top the phone",
"age": 72,
"birthday": "2014-05-13T16:53:20Z",
"title": "mizz"
}

View File

@@ -0,0 +1,27 @@
{
"types": {
"person": {
"properties": {
"name": {
"fields": [
{
"include_term_vectors": true,
"include_in_all": true,
"index": true,
"store": true,
"analyzer": "en",
"type": "text"
}
],
"dynamic": true,
"enabled": true
},
"id": {
"dynamic": false,
"enabled": false
}
}
}
},
"default_type": "person"
}

View File

@@ -0,0 +1,883 @@
[
{
"comment": "test term search, exact match",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"term": "marti"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"comment": "test term search, no match",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"term": "noone"
}
},
"result": {
"total_hits": 0,
"hits": []
}
},
{
"comment": "test match phrase search",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"match_phrase": "steve has"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b"
}
]
}
},
{
"comment": "test term search, no match",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"term": "walking"
}
},
"result": {
"total_hits": 0,
"hits": []
}
},
{
"comment": "test match search, matching due to analysis",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"fuzziness": 0,
"prefix_length": 0,
"field": "name",
"match": "walking"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "c"
}
]
}
},
{
"comment": "test term prefix search",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"prefix": "bobble"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "d"
}
]
}
},
{
"comment": "test simple query string",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"query": "+name:phone"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "d"
}
]
}
},
{
"comment": "test numeric range, no lower bound",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "age",
"max": 30
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "a"
},
{
"id": "b"
}
]
}
},
{
"comment": "test numeric range, upper and lower bounds",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "age",
"max": 30,
"min": 20
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b"
}
]
}
},
{
"comment": "test conjunction of numeric range, upper and lower bounds",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"conjuncts": [
{
"boost": 1,
"field": "age",
"min": 20
},
{
"boost": 1,
"field": "age",
"max": 30
}
]
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b"
}
]
}
},
{
"comment": "test date range, no upper bound",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "birthday",
"start": "2010-01-01"
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "c"
},
{
"id": "d"
}
]
}
},
{
"comment": "test numeric range, no lower bound",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "birthday",
"end": "2010-01-01"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b"
}
]
}
},
{
"comment": "test term search, matching inside an array",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "tags",
"term": "gopher"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"comment": "test term search, matching another element inside array",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "tags",
"term": "belieber"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"comment": "test term search, not present in array",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "tags",
"term": "notintagsarray"
}
},
"result": {
"total_hits": 0,
"hits": []
}
},
{
"comment": "with size 0, total should be 1, but hits empty",
"search": {
"from": 0,
"size": 0,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"term": "marti"
}
},
"result": {
"total_hits": 1,
"hits": []
}
},
{
"comment": "a search for doc a that includes tags field, verifies both values come back",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"fields": ["tags"],
"query": {
"field": "name",
"term": "marti"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a",
"fields": {
"tags": ["gopher", "belieber"]
}
}
]
}
},
{
"comment": "test fuzzy search, fuzziness 1 with match",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"term": "msrti",
"fuzziness": 1
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"comment": "highlight results",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"match": "long"
},
"highlight": {
"fields": ["name"]
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b",
"fragments": {
"name": ["steve has &lt;a&gt; <mark>long</mark> &amp; complicated name"]
}
}
]
}
},
{
"comment": "highlight results without specifying fields",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"match": "long"
},
"highlight": {}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b",
"fragments": {
"name": ["steve has &lt;a&gt; <mark>long</mark> &amp; complicated name"]
}
}
]
}
},
{
"comment": "request fields",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"fields": ["age","birthday"],
"query": {
"field": "name",
"match": "long"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b",
"fields": {
"age": 27,
"birthday": "2001-09-09T01:46:40Z"
}
}
]
}
},
{
"comment": "tests query string only containing MUST NOT clause, bug #193",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"query": "-title:mista"
}
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "b"
},
{
"id": "c"
},
{
"id": "d"
}
]
}
},
{
"comment": "highlight results including non-matching field (which should be produced in its entirety, though unhighlighted)",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"match": "long"
},
"highlight": {
"fields": ["name", "title"]
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b",
"fragments": {
"name": ["steve has &lt;a&gt; <mark>long</mark> &amp; complicated name"],
"title": ["missess"]
}
}
]
}
},
{
"comment": "search and highlight an array field",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "tags",
"match": "gopher"
},
"highlight": {
"fields": ["tags"]
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a",
"fragments": {
"tags": ["<mark>gopher</mark>"]
}
}
]
}
},
{
"comment": "reproduce bug in prefix search",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "title",
"prefix": "miss"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b"
}
]
}
},
{
"comment": "test match none",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"match_none": {}
}
},
"result": {
"total_hits": 0,
"hits": []
}
},
{
"comment": "test match all",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"match_all": {}
}
},
"result": {
"total_hits": 4,
"hits": [
{
"id": "a"
},
{
"id": "b"
},
{
"id": "c"
},
{
"id": "d"
}
]
}
},
{
"comment": "test doc id query",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"ids": ["b", "c"]
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "b"
},
{
"id": "c"
}
]
}
},
{
"comment": "test query string MUST and SHOULD",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"query": "+age:>20 missess"
}
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "b"
},
{
"id": "c"
},
{
"id": "d"
}
]
}
},
{
"comment": "test regexp matching term",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"regexp": "mar.*"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"comment": "test regexp that should not match when properly anchored",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"regexp": "mar."
}
},
"result": {
"total_hits": 0,
"hits": []
}
},
{
"comment": "test wildcard matching term",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "name",
"wildcard": "mar*"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"comment": "test boost - term query",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"disjuncts": [
{
"field": "name",
"term": "marti",
"boost": 1.0
},
{
"field": "name",
"term": "steve",
"boost": 5.0
}
]
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "b"
},
{
"id": "a"
}
]
}
},
{
"comment": "test boost - term query",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"disjuncts": [
{
"field": "name",
"term": "marti",
"boost": 1.0
},
{
"fuzziness": 1,
"field": "name",
"term": "steve",
"boost": 5.0
}
]
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "b"
},
{
"id": "a"
}
]
}
},
{
"comment": "test boost - numeric range query",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"disjuncts": [
{
"field": "name",
"term": "marti",
"boost": 1.0
},
{
"field": "age",
"min": 25,
"max": 29,
"boost": 50.0
}
]
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "b"
},
{
"id": "a"
}
]
}
},
{
"comment": "test boost - regexp query",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"disjuncts": [
{
"field": "name",
"term": "marti",
"boost": 1.0
},
{
"field": "name",
"regexp": "stev.*",
"boost": 5.0
}
]
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "b"
},
{
"id": "a"
}
]
}
},
{
"comment": "test wildcard inside query string",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"query": "name:mar*"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"comment": "test regexp inside query string",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"query": "name:/mar.*/"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"comment": "test term range",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "title",
"max": "miz",
"min": "mis"
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "a"
},
{
"id": "b"
}
]
}
}
]

View File

@@ -0,0 +1,44 @@
{
"salary": 104561.8,
"_type": "emp",
"name": "Deirdre Reed",
"mutated": 0,
"is_manager": true,
"dept": "Accounts",
"join_date": "2003-05-28T21:29:00",
"manages": {
"team_size": 9,
"reports": [
"Gallia Julián",
"Duvessa Nicolás",
"Beryl Thomas",
"Deirdre Julián",
"Antonia Gerónimo",
"Ciara Young",
"Riona Richardson IX",
"Severin Jr.",
"Perdita Morgan"
]
},
"languages_known": [
"English",
"Spanish",
"German",
"Italian",
"French",
"Arabic",
"Africans",
"Hindi",
"Vietnamese",
"Urdu",
"Dutch",
"Quechua",
"Japanese",
"Chinese",
"Nepalese",
"Thai",
"Malay"
],
"emp_id": "10508560",
"email": "deirdre@mcdiabetes.com"
}

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,41 @@
[
{
"comment": "test array position output",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "manages.reports",
"term": "julián"
},
"includeLocations": true
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "emp10508560",
"locations": {
"manages.reports": {
"julián": [
{
"pos": 2,
"start": 7,
"end": 14,
"array_positions":[0]
},
{
"pos": 2,
"start": 8,
"end": 15,
"array_positions":[3]
}
]
}
}
}
]
}
}
]

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "book",
"rating": 2,
"updated": "2014-11-25"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "book",
"rating": 7,
"updated": "2013-07-25"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "book",
"rating": 1,
"updated": "2014-03-03"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "book",
"rating": 9,
"updated": "2014-09-16"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "book",
"rating": 5,
"updated": "2014-11-15"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "movie",
"rating": 3,
"updated": "2017-06-05"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "movie",
"rating": 9,
"updated": "2011-10-03"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "movie",
"rating": 9,
"updated": "2019-08-26"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "movie",
"rating": 1,
"updated": "2014-12-14"
}

View File

@@ -0,0 +1,6 @@
{
"category": "inventory",
"type": "game",
"rating": 9,
"updated": "2013-10-20"
}

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,144 @@
[
{
"search": {
"from": 0,
"size": 0,
"query": {
"field": "category",
"term": "inventory"
},
"facets": {
"types": {
"size": 3,
"field": "type"
}
}
},
"result": {
"total_hits": 10,
"hits": [],
"facets": {
"types": {
"field": "type",
"total": 10,
"missing": 0,
"other": 0,
"terms": [
{
"term": "book",
"count": 5
},
{
"term": "movie",
"count": 4
},
{
"term": "game",
"count": 1
}
]
}
}
}
},
{
"search": {
"from": 0,
"size": 0,
"query": {
"field": "category",
"term": "inventory"
},
"facets": {
"types": {
"size": 3,
"field": "rating",
"numeric_ranges": [
{
"name": "low",
"max": 5
},
{
"name": "high",
"min": 5
}
]
}
}
},
"result": {
"total_hits": 10,
"hits": [],
"facets": {
"types": {
"field": "rating",
"total": 10,
"missing": 0,
"other": 0,
"numeric_ranges": [
{
"name": "high",
"count": 6,
"min": 5
},
{
"name": "low",
"count": 4,
"max": 5
}
]
}
}
}
},
{
"search": {
"from": 0,
"size": 0,
"query": {
"field": "category",
"term": "inventory"
},
"facets": {
"types": {
"size": 3,
"field": "updated",
"date_ranges": [
{
"name": "old",
"end": "2012-01-01"
},
{
"name": "new",
"start": "2012-01-01"
}
]
}
}
},
"result": {
"total_hits": 10,
"hits": [],
"facets": {
"types": {
"field": "updated",
"total": 10,
"missing": 0,
"other": 0,
"date_ranges": [
{
"name": "new",
"count": 9,
"start": "2012-01-01T00:00:00Z"
},
{
"name": "old",
"count": 1,
"end": "2012-01-01T00:00:00Z"
}
]
}
}
}
}
]

View File

@@ -0,0 +1,4 @@
{
"description": "From Prolog to Erlang to Haskell to Lisp to TLC and then back to Prolog I have journeyed, and I'd like to share some of the beautiful",
"category": "Word"
}

View File

@@ -0,0 +1,4 @@
{
"description": "different cats",
"category": "Perl"
}

View File

@@ -0,0 +1,4 @@
{
"description": "many cats",
"category": "Perl"
}

View File

@@ -0,0 +1,4 @@
{
"description": "From Prolog to Erlang to Haskell to Lisp to TLC and then back to Prolog I have journeyed, and I'd like to share some of the beautiful",
"category": "Perl"
}

View File

@@ -0,0 +1,4 @@
{
"description": "From Prolog to Erlang to Haskell to Gel to TLC and then back to Prolog I have journeyed, and I'd like to share some of the beautiful",
"category": "Perl"
}

View File

@@ -0,0 +1,76 @@
{
"default_mapping": {
"enabled": true,
"dynamic": true,
"properties": {
"category": {
"enabled": true,
"dynamic": true,
"fields": [
{
"type": "text",
"analyzer": "keyword",
"store": true,
"index": true,
"include_term_vectors": true,
"include_in_all": true
}
],
"default_analyzer": ""
},
"description": {
"enabled": true,
"dynamic": true,
"fields": [
{
"type": "text",
"analyzer": "en",
"store": true,
"index": true,
"include_term_vectors": true,
"include_in_all": true
}
],
"default_analyzer": ""
},
"summary": {
"enabled": true,
"dynamic": true,
"fields": [
{
"type": "text",
"analyzer": "en",
"store": true,
"index": true,
"include_term_vectors": true,
"include_in_all": true
}
],
"default_analyzer": ""
},
"url": {
"enabled": true,
"dynamic": true,
"fields": [
{
"type": "text",
"analyzer": "keyword",
"store": true,
"index": true,
"include_term_vectors": true,
"include_in_all": true
}
],
"default_analyzer": ""
}
},
"default_analyzer": ""
},
"type_field": "_type",
"default_type": "_default",
"default_analyzer": "en",
"default_datetime_parser": "dateTimeOptional",
"default_field": "_all",
"byte_array_converter": "json",
"analysis": {}
}

View File

@@ -0,0 +1,109 @@
[
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "category",
"match_phrase": "Perl"
}
},
"result": {
"total_hits": 4,
"hits": [
{
"id": "3492@FOSDEM15@fosdem.org"
},
{
"id": "3496@FOSDEM15@fosdem.org"
},
{
"id": "3505@FOSDEM15@fosdem.org"
},
{
"id": "3507@FOSDEM15@fosdem.org"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"match": "lisp"
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "3311@FOSDEM15@fosdem.org"
},
{
"id": "3505@FOSDEM15@fosdem.org"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {"boost":1,"query":"+lisp +category:Perl"}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "3505@FOSDEM15@fosdem.org"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {"boost":1,"query":"+lisp +category:\"Perl\""}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "3505@FOSDEM15@fosdem.org"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"must": {
"conjuncts":[
{"boost":1,"query":"+cats"},
{"field":"category","match_phrase":"Perl"}
]
}
}
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "3492@FOSDEM15@fosdem.org"
},
{
"id": "3496@FOSDEM15@fosdem.org"
}
]
}
}
]

View File

@@ -0,0 +1 @@
{"name":"amoeba brewery","city":"bangalore","state":"KAR","code":"","country":"India","phone":"","website":"","type":"brewery","updated":"2019-09-17 20:00:20","description":"brewery near cb office","address":[],"geo":{"accuracy":"APPROXIMATE","lat":12.97467,"lon":77.60490}}

View File

@@ -0,0 +1 @@
{"name":"Brewpub-on-the-Green","city":"Fremont","state":"California","code":"","country":"United States","phone":"","website":"","type":"brewery","updated":"2010-07-22 20:00:20","description":"","address":[],"geo":{"accuracy":"APPROXIMATE","lat":37.5483,"lon":-121.989}}

View File

@@ -0,0 +1 @@
{"name":"Capital City Brewing Company","city":"Washington","state":"District of Columbia","code":"20005","country":"United States","phone":"202.628.2222","website":"http://www.capcitybrew.com","type":"brewery","updated":"2010-07-22 20:00:20","description":"Washington DC's first brewpub since prohibition, Capitol City Brewing Co. opened its doors in 1992. Our first location still stands in Downtown DC, at 11th and H St., NW. Our company policy is to bring the fine craft of brewing to every person who lives and visits our region, as well as treating them to a wonderful meal and a great experience.","address":["1100 New York Ave, NW"],"geo":{"accuracy":"ROOFTOP","lat":38.8999,"lon":-77.0272}}

View File

@@ -0,0 +1 @@
{"name":"communiti brewery","city":"bangalore","state":"KAR","code":"","country":"India","phone":"","website":"","type":"brewery","updated":"2019-09-17 20:00:20","description":"brewery near cb office","address":[],"geo":{"accuracy":"APPROXIMATE","lat":12.97237,"lon":77.608237}}

View File

@@ -0,0 +1 @@
{"name":"Firehouse Grill & Brewery","city":"Sunnyvale","state":"California","code":"94086","country":"United States","phone":"1-408-773-9500","website":"","type":"brewery","updated":"2010-07-22 20:00:20","description":"","address":["111 South Murphy Avenue"],"geo":{"accuracy":"RANGE_INTERPOLATED","lat":37.3775,"lon":-122.03}}

View File

@@ -0,0 +1 @@
{"name":"Hook & Ladder Brewing Company","city":"Silver Spring","state":"Maryland","code":"20910","country":"United States","phone":"301.565.4522","website":"http://www.hookandladderbeer.com","type":"brewery","updated":"2010-07-22 20:00:20","description":"At Hook & Ladder Brewing we believe in great beer in the company of good friends, so we bring you three great beers for your drinking pleasure (please drink responsibly). Each of our beers is carefully crafted with the finest quality ingredients for a distinctive taste we know you will enjoy. Try one tonight, you just might get hooked. Through our own experiences in the fire and rescue service we have chosen the Hook & Ladder as a symbol of pride and honor to pay tribute to the brave men and women who serve and protect our communities.","address":["8113 Fenton St."],"geo":{"accuracy":"ROOFTOP","lat":38.9911,"lon":-77.0237}}

View File

@@ -0,0 +1 @@
{"name":"Jack's Brewing","city":"Fremont","state":"California","code":"94538","country":"United States","phone":"1-510-796-2036","website":"","type":"brewery","updated":"2010-07-22 20:00:20","description":"","address":["39176 Argonaut Way"],"geo":{"accuracy":"ROOFTOP","lat":37.5441,"lon":-121.988}}

View File

@@ -0,0 +1 @@
{"name":"social brewery","city":"bangalore","state":"KAR","code":"","country":"India","phone":"","website":"","type":"brewery","updated":"2019-09-17 20:00:20","description":"brewery near cb office, but outside the polygon","address":[],"geo":{"accuracy":"APPROXIMATE","lat":12.9736946,"lon":77.6042133}}

View File

@@ -0,0 +1 @@
{"name":"Sweet Water Tavern and Brewery","city":"Sterling","state":"Virginia","code":"20121","country":"United States","phone":"(703) 449-1108","website":"http://www.greatamericanrestaurants.com/sweetMainSter/index.htm","type":"brewery","updated":"2010-07-22 20:00:20","description":"","address":["45980 Waterview Plaza"],"geo":{"accuracy":"RANGE_INTERPOLATED","lat":39.0324,"lon":-77.4097}}

View File

@@ -0,0 +1,36 @@
{
"types": {
"brewery": {
"properties": {
"name": {
"fields": [
{
"include_term_vectors": true,
"include_in_all": true,
"index": true,
"store": true,
"analyzer": "keyword",
"type": "text"
}
],
"dynamic": true,
"enabled": true
},
"geo": {
"fields": [
{
"include_term_vectors": true,
"include_in_all": true,
"index": true,
"store": true,
"type": "geopoint"
}
],
"dynamic": true,
"enabled": true
}
}
}
},
"default_type": "brewery"
}

View File

@@ -0,0 +1,326 @@
[
{
"comment": "breweries near the couchbase office",
"search": {
"from": 0,
"size": 10,
"query": {
"location": {
"lon": -122.107799,
"lat": 37.399285
},
"distance": "100mi",
"field": "geo"
},
"sort": [
{
"by": "geo_distance",
"field": "geo",
"unit": "mi",
"location": {
"lon": -122.107799,
"lat": 37.399285
}
}
]
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "firehouse_grill_brewery"
},
{
"id": "jack_s_brewing"
},
{
"id": "brewpub_on_the_green"
}
]
}
},
{
"comment": "breweries near the whitehouse",
"search": {
"from": 0,
"size": 10,
"query": {
"location": {
"lon": -77.0365,
"lat": 38.8977
},
"distance": "100mi",
"field": "geo"
},
"sort": [
{
"by": "geo_distance",
"field": "geo",
"unit": "mi",
"location": {
"lon": -77.0365,
"lat": 38.8977
}
}
]
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "capital_city_brewing_company"
},
{
"id": "hook_ladder_brewing_company"
},
{
"id": "sweet_water_tavern_and_brewery"
}
]
}
},
{
"comment": "bounding box of USA",
"search": {
"from": 0,
"size": 10,
"query": {
"top_left": {
"lon": -125.0011,
"lat": 49.5904
},
"bottom_right": {
"lon": -66.9326,
"lat": 24.9493
},
"field": "geo"
},
"sort": [
"name"
]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "brewpub_on_the_green"
},
{
"id": "capital_city_brewing_company"
},
{
"id": "firehouse_grill_brewery"
},
{
"id": "hook_ladder_brewing_company"
},
{
"id": "jack_s_brewing"
},
{
"id": "sweet_water_tavern_and_brewery"
}
]
}
},
{
"comment": "bounding box around DC area",
"search": {
"from": 0,
"size": 10,
"query": {
"top_left": {
"lon": -78,
"lat": 39.5
},
"bottom_right": {
"lon": -76,
"lat": 38.5
},
"field": "geo"
},
"sort": [
"name"
]
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "capital_city_brewing_company"
},
{
"id": "hook_ladder_brewing_company"
},
{
"id": "sweet_water_tavern_and_brewery"
}
]
}
},
{
"comment": "breweries near the couchbase office, using GeoJSON style points",
"search": {
"from": 0,
"size": 10,
"query": {
"location": [-122.107799,37.399285],
"distance": "100mi",
"field": "geo"
},
"sort": [
{
"by": "geo_distance",
"field": "geo",
"unit": "mi",
"location": [-122.107799,37.399285]
}
]
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "firehouse_grill_brewery"
},
{
"id": "jack_s_brewing"
},
{
"id": "brewpub_on_the_green"
}
]
}
},
{
"comment": "bounding box around DC area, using GeoJSON style",
"search": {
"from": 0,
"size": 10,
"query": {
"top_left": [-78,39.5],
"bottom_right": [-76,38.5],
"field": "geo"
},
"sort": [
"name"
]
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "capital_city_brewing_company"
},
{
"id": "hook_ladder_brewing_company"
},
{
"id": "sweet_water_tavern_and_brewery"
}
]
}
},
{
"comment": "polygon around cb office area, using GeoJSON lat/lon as array",
"search": {
"from": 0,
"size": 10,
"query": {
"polygon_points": [[77.607749,12.974872],[77.6101101,12.971725],[77.606912,12.972530],[77.603780,12.975112]],
"field": "geo"
},
"sort": [
"name"
]
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "amoeba_brewery"
},
{
"id": "communiti_brewery"
}
]
}
},
{
"comment": "polygon around cb office area, using GeoJSON lat/lon as string",
"search": {
"from": 0,
"size": 10,
"query": {
"polygon_points": ["12.974872, 77.607749","12.971725, 77.6101101","12.972530, 77.606912","12.975112, 77.603780"],
"field": "geo"
},
"sort": [
"name"
]
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "amoeba_brewery"
},
{
"id": "communiti_brewery"
}
]
}
},
{
"comment": "polygon around cb office area",
"search": {
"from": 0,
"size": 10,
"query": {
"polygon_points": [{"lat":12.974872, "lon":77.607749}, {"lat":12.971725, "lon":77.6101101},
{"lat":12.972530, "lon":77.606912}, {"lat":12.975112, "lon":77.603780}],
"field": "geo"
},
"sort": [
"name"
]
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "amoeba_brewery"
},
{
"id": "communiti_brewery"
}
]
}
},
{
"comment": "polygon around cb office area as geohash",
"search": {
"from": 0,
"size": 10,
"query": {
"polygon_points": ["tdr1y40", "tdr1y13", "tdr1vcx", "tdr1vfj"],
"field": "geo"
},
"sort": [
"name"
]
},
"result": {
"total_hits": 2,
"hits": [
{
"id": "amoeba_brewery"
},
{
"id": "communiti_brewery"
}
]
}
}
]

View File

@@ -0,0 +1,14 @@
{
"name": "hal airpork circular region",
"city": "bangalore",
"type": "geoshapes",
"description": "circle covering the hal airport",
"region": {
"type": "Circle",
"coordinates": [
77.6698637008667,
12.951865687866821
],
"radius": "2.4km"
}
}

View File

@@ -0,0 +1,19 @@
{
"name": "brockwell park envelope",
"city": "london",
"type": "geoshapes",
"description": "brockwell park envelope",
"region": {
"type": "envelope",
"coordinates": [
[
-0.11278152465820314,
51.44579626059569
],
[
-0.10037899017333984,
51.45566490761856
]
]
}
}

View File

@@ -0,0 +1,165 @@
{
"name": "geometrycollection comprised of various shapes",
"city": "bangalore",
"type": "geoshapes",
"description": "geometrycollection comprised of various shapes",
"region": {
"type": "geometrycollection",
"geometries": [
{
"type": "point",
"coordinates": [
76.92815780639648,
8.525851789596233
]
},
{
"type": "LineString",
"coordinates": [
[
76.92867279052734,
8.490369393806219
],
[
76.94377899169922,
8.494104537551882
]
]
},
{
"type": "polygon",
"coordinates": [
[
[
76.92815780639648,
8.525851789596233
],
[
76.92060470581055,
8.520504174874656
],
[
76.92206382751465,
8.519061154914393
],
[
76.92824363708496,
8.519061154914393
],
[
76.92970275878906,
8.523475081176768
],
[
76.92815780639648,
8.525851789596233
]
]
]
},
{
"type": "multipoint",
"coordinates": [
[
76.90670013427733,
8.497839644932787
],
[
76.94137573242188,
8.485275957394883
]
]
},
{
"type": "multiLineString",
"coordinates": [
[
[
76.89322471618651,
8.521522773921424
],
[
76.89648628234863,
8.518042549311815
]
],
[
[
76.9068717956543,
8.494783650690053
],
[
76.93296432495117,
8.468552033040881
]
]
]
},
{
"type": "multipolygon",
"coordinates": [
[
[
[
76.90249443054199,
8.546138091708775
],
[
76.89983367919922,
8.541300033890494
],
[
76.90498352050781,
8.53985709248573
],
[
76.90858840942383,
8.54520443620746
],
[
76.90712928771973,
8.548090273095957
],
[
76.90249443054199,
8.546138091708775
]
]
],
[
[
[
76.88326835632324,
8.564131732621458
],
[
76.88429832458496,
8.555729147617923
],
[
76.88893318176268,
8.552079482230221
],
[
76.89339637756348,
8.55369212938781
],
[
76.89494132995605,
8.56133089156368
],
[
76.89116477966309,
8.566423314514562
],
[
76.88326835632324,
8.564131732621458
]
]
]
]
}
]
}
}

View File

@@ -0,0 +1,19 @@
{
"name": "linestring for putney bridge",
"city": "london",
"type": "geoshapes",
"description": "linestring for putney bridge",
"region": {
"type": "linestring",
"coordinates": [
[
-0.21183013916015625,
51.46791083061189
],
[
-0.21431922912597656,
51.465504685939706
]
]
}
}

View File

@@ -0,0 +1,48 @@
{
"name": "road routes",
"city": "bangalore",
"type": "geoshapes",
"description": "multilinestrings approximating the roads indiranagar 100ft and old airport port road",
"region": {
"type": "multilinestring",
"coordinates": [
[
[
77.64081001281738,
12.983398626256326
],
[
77.64166831970213,
12.960648472679763
]
],
[ [
77.64192581176758,
12.960564828571133
],
[
77.66990661621094,
12.958390071883693
]
],
[ [
77.67016410827637,
12.958055492245812
],
[
77.68106460571289,
12.954626025039444
]
],
[ [
77.68149375915527,
12.954542378907867
],
[
77.7011489868164,
12.957219041184294
]
]
]
}
}

View File

@@ -0,0 +1,23 @@
{
"name": "multipoints for stadiums",
"city": "bangalore",
"type": "geoshapes",
"description": "contains 3 points",
"region": {
"type": "multipoint",
"coordinates": [
[
77.5929594039917,
12.969347306502671
],
[
77.6004695892334,
12.979007674139009
],
[
77.60068416595459,
12.961735843534306
]
]
}
}

View File

@@ -0,0 +1,87 @@
{
"name": "london parks as multipolygon",
"city": "london",
"type": "geoshapes",
"description": "multipolygon with london",
"region": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-0.163421630859375,
51.531600743186644
],
[
-0.15277862548828125,
51.52455221546295
],
[
-0.14556884765625,
51.524979430024345
],
[
-0.14591217041015625,
51.536085601784755
],
[
-0.15895843505859375,
51.53693981046689
],
[
-0.163421630859375,
51.531600743186644
]
]
],
[
[
[
-0.1902008056640625,
51.5091698216777
],
[
-0.1888275146484375,
51.50147667659363
],
[
-0.15071868896484375,
51.503186376638006
],
[
-0.1599884033203125,
51.51322956905176
],
[
-0.1902008056640625,
51.5091698216777
]
]
],
[
[
[
-0.16582489013671875,
51.4811690848672
],
[
-0.1635932922363281,
51.474861202507434
],
[
-0.14883041381835938,
51.47764105478667
],
[
-0.14951705932617188,
51.48352095330697
],
[
-0.16582489013671875,
51.4811690848672
]
]
]
]
}
}

View File

@@ -0,0 +1,13 @@
{
"name": "geopoint for the museum of london",
"city": "london",
"type": "geoshapes",
"description": "geopoint for the museum of london",
"region": {
"type": "point",
"coordinates": [
-0.09613037109375,
51.51803669675129
]
}
}

View File

@@ -0,0 +1,45 @@
{
"name": "cubbon park polygon",
"city": "bangalore",
"type": "geoshapes",
"description": "polygon inside cubbon park",
"region": {
"type": "Polygon",
"coordinates": [
[
[
77.58894681930542,
12.976498523818783
],
[
77.58677959442139,
12.974533005048169
],
[
77.5879168510437,
12.971333776381767
],
[
77.58849620819092,
12.96800904416803
],
[
77.59371042251587,
12.972128359891645
],
[
77.59512662887573,
12.973842978816679
],
[
77.59253025054932,
12.976853988320428
],
[
77.58894681930542,
12.976498523818783
]
]
]
}
}

View File

@@ -0,0 +1,36 @@
{
"types": {
"geoshapes": {
"properties": {
"name": {
"fields": [
{
"include_term_vectors": true,
"include_in_all": true,
"index": true,
"store": true,
"analyzer": "keyword",
"type": "text"
}
],
"dynamic": true,
"enabled": true
},
"region": {
"fields": [
{
"include_term_vectors": true,
"include_in_all": true,
"index": true,
"store": true,
"type": "geoshape"
}
],
"dynamic": true,
"enabled": true
}
}
}
},
"default_type": "geoshapes"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
{
"body": "Twenty Thousand Leagues Under The Sea"
}

View File

@@ -0,0 +1,3 @@
{
"body": ["bad call", "defenseless receiver"]
}

View File

@@ -0,0 +1,23 @@
{
"types": {
"book": {
"properties": {
"body": {
"fields": [
{
"include_term_vectors": true,
"include_in_all": true,
"index": true,
"store": true,
"analyzer": "en",
"type": "text"
}
],
"dynamic": true,
"enabled": true
}
}
}
},
"default_type": "book"
}

View File

@@ -0,0 +1,417 @@
[
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Twenty"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Twenty Thousand"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Twenty Thousand Leagues"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Twenty Thousand Leagues Under"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Twenty Thousand Leagues Under the"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Twenty Thousand Leagues Under the Sea"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Thousand"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Thousand Leagues"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Thousand Leagues Under"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Thousand Leagues Under the"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Thousand Leagues Under the Sea"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Leagues"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Leagues Under"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Leagues Under the"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Leagues Under the Sea"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Under the Sea"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "the Sea"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "Sea"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "bad call"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "defenseless receiver"
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "b"
}
]
}
},
{
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"match_phrase": "bad receiver"
}
},
"result": {
"total_hits": 0,
"hits": []
}
},
{
"comment": "multi-phrase terms",
"search": {
"from": 0,
"size": 10,
"sort": ["-_score", "_id"],
"query": {
"field": "body",
"terms": [["twenti","thirti"],["thousand"]]
}
},
"result": {
"total_hits": 1,
"hits": [
{
"id": "a"
}
]
}
}
]

View File

@@ -0,0 +1,8 @@
{
"id": "a",
"name": "marty",
"age": 19,
"born": "2014-11-25",
"title": "mista",
"tags": ["gopher", "belieber"]
}

View File

@@ -0,0 +1,8 @@
{
"id": "b",
"name": "steve",
"age": 21,
"born": "2000-09-11",
"title": "zebra",
"tags": ["thought-leader", "futurist"]
}

View File

@@ -0,0 +1,8 @@
{
"id": "c",
"name": "aster",
"age": 21,
"born": "1954-02-02",
"title": "blogger",
"tags": ["red", "blue", "green"]
}

View File

@@ -0,0 +1,7 @@
{
"id": "d",
"age": 65,
"born": "1978-12-02",
"title": "agent d is desperately trying out to be successful rapster!",
"tags": ["cats"]
}

View File

@@ -0,0 +1,7 @@
{
"id": "e",
"name": "nancy",
"born": "1954-10-22",
"title": "rapstar nancy rapster",
"tags": ["pain"]
}

View File

@@ -0,0 +1,7 @@
{
"id": "f",
"name": "frank",
"age": 1,
"title": "frank the taxman of cb, Rapster!",
"tags": ["vitamin","purple"]
}

View File

@@ -0,0 +1,3 @@
{
}

View File

@@ -0,0 +1,554 @@
[
{
"comment": "sort by name, ascending",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["name"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "c"
},
{
"id": "f"
},
{
"id": "a"
},
{
"id": "e"
},
{
"id": "b"
},
{
"id": "d"
}
]
}
},
{
"comment": "sort by name, descending",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["-name"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "b"
},
{
"id": "e"
},
{
"id": "a"
},
{
"id": "f"
},
{
"id": "c"
},
{
"id": "d"
}
]
}
},
{
"comment": "sort by name, descending, missing first",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": [{"by":"field","field":"name","missing":"first","desc":true}]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "d"
},
{
"id": "b"
},
{
"id": "e"
},
{
"id": "a"
},
{
"id": "f"
},
{
"id": "c"
}
]
}
},
{
"comment": "sort by age, ascending, _id, ascending",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["age", "_id"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "f"
},
{
"id": "a"
},
{
"id": "b"
},
{
"id": "c"
},
{
"id": "d"
},
{
"id": "e"
}
]
}
},
{
"comment": "sort by age, descending, _id, ascending",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["-age", "_id"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "d"
},
{
"id": "b"
},
{
"id": "c"
},
{
"id": "a"
},
{
"id": "f"
},
{
"id": "e"
}
]
}
},
{
"comment": "sort by age, descending, missing first, id, ascending",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": [{"by":"field","field":"age","missing":"first","desc":true},{"by":"id","desc":false}]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "e"
},
{
"id": "d"
},
{
"id": "b"
},
{
"id": "c"
},
{
"id": "a"
},
{
"id": "f"
}
]
}
},
{
"comment": "sort by born, ascending",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["born"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "c"
},
{
"id": "e"
},
{
"id": "d"
},
{
"id": "b"
},
{
"id": "a"
},
{
"id": "f"
}
]
}
},
{
"comment": "sort by born, descending",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["-born"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "a"
},
{
"id": "b"
},
{
"id": "d"
},
{
"id": "e"
},
{
"id": "c"
},
{
"id": "f"
}
]
}
},
{
"comment": "sort by born, descending, missing first",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": [{"by":"field","field":"born","missing":"first","desc":true}]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "f"
},
{
"id": "a"
},
{
"id": "b"
},
{
"id": "d"
},
{
"id": "e"
},
{
"id": "c"
}
]
}
},
{
"comment": "sort on multi-valued field",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": [{"by":"field","field":"tags","mode":"min"}]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "a"
},
{
"id": "c"
},
{
"id": "d"
},
{
"id": "b"
},
{
"id": "e"
},
{
"id": "f"
}
]
}
},
{
"comment": "multi-column sort by age, ascending, name, ascending (flips b and c which have same age)",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["age", "name"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "f"
},
{
"id": "a"
},
{
"id": "c"
},
{
"id": "b"
},
{
"id": "d"
},
{
"id": "e"
}
]
}
},
{
"comment": "sort by docid descending",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["-_id"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "f"
},
{
"id": "e"
},
{
"id": "d"
},
{
"id": "c"
},
{
"id": "b"
},
{
"id": "a"
}
]
}
},
{
"comment": "sort by name, ascending, after marty",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["name"],
"search_after": ["marty"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "e"
},
{
"id": "b"
},
{
"id": "d"
}
]
}
},
{
"comment": "sort by name, ascending, before nancy",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["name"],
"search_before": ["nancy"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "c"
},
{
"id": "f"
},
{
"id": "a"
}
]
}
},
{
"comment": "sort by ID, after doc d",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["_id"],
"search_after": ["d"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "e"
},
{
"id": "f"
}
]
}
},
{
"comment": "sort by ID, before doc d",
"search": {
"from": 0,
"size": 10,
"query": {
"match_all":{}
},
"sort": ["_id"],
"search_before": ["d"]
},
"result": {
"total_hits": 6,
"hits": [
{
"id": "a"
},
{
"id": "b"
},
{
"id": "c"
}
]
}
},
{
"comment": "sort by score, after score 0.286889[ e(299646) > f(286889) > d(222224)]",
"search": {
"from": 0,
"size": 10,
"query": {
"query":"rapster"
},
"sort": ["_score"],
"search_after": ["0.286889"]
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "f"
},
{
"id": "e"
}
]
}
},
{
"comment": "sort by score, before score f/0.286889[ e(299646) > f(286889) > d(222224)]",
"search": {
"from": 0,
"size": 10,
"query": {
"query":"rapster"
},
"sort": ["_score"],
"search_before": ["0.286889"]
},
"result": {
"total_hits": 3,
"hits": [
{
"id": "d"
}
]
}
}
]

140
test/versus_score_test.go Normal file
View File

@@ -0,0 +1,140 @@
// Copyright (c) 2018 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 test
import (
"os"
"strconv"
"testing"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/document"
"github.com/blevesearch/bleve/v2/index/scorch"
"github.com/blevesearch/bleve/v2/index/upsidedown"
"github.com/blevesearch/bleve/v2/mapping"
"github.com/blevesearch/bleve/v2/search"
index "github.com/blevesearch/bleve_index_api"
)
func TestDisjunctionSearchScoreIndexWithCompositeFields(t *testing.T) {
upHits := disjunctionQueryiOnIndexWithCompositeFields(upsidedown.Name, t)
scHits := disjunctionQueryiOnIndexWithCompositeFields(scorch.Name, t)
if upHits[0].ID != scHits[0].ID || upHits[1].ID != scHits[1].ID {
t.Errorf("upsidedown, scorch returned different docs;\n"+
"upsidedown: (%s, %s), scorch: (%s, %s)\n",
upHits[0].ID, upHits[1].ID, scHits[0].ID, scHits[1].ID)
}
if scHits[0].Score != upHits[0].Score || scHits[1].Score != upHits[1].Score {
t.Errorf("upsidedown, scorch showing different scores;\n"+
"upsidedown: (%+v, %+v), scorch: (%+v, %+v)\n",
*upHits[0].Expl, *upHits[1].Expl, *scHits[0].Expl, *scHits[1].Expl)
}
}
func disjunctionQueryiOnIndexWithCompositeFields(indexName string,
t *testing.T,
) []*search.DocumentMatch {
tmpIndexPath, err := os.MkdirTemp("", "bleve-testidx")
if err != nil {
t.Fatalf("error creating temp dir: %v", err)
}
defer func() {
err := os.RemoveAll(tmpIndexPath)
if err != nil {
t.Fatalf("error removing temp dir: %v", err)
}
}()
// create an index
idxMapping := mapping.NewIndexMapping()
idx, err := bleve.NewUsing(tmpIndexPath, idxMapping, indexName,
bleve.Config.DefaultKVStore, nil)
if err != nil {
t.Error(err)
}
defer func() {
err = idx.Close()
if err != nil {
t.Error(err)
}
}()
// create and insert documents as a batch
batch := idx.NewBatch()
docs := []struct {
field1 string
field2 int
}{
{
field1: "one",
field2: 1,
},
{
field1: "two",
field2: 2,
},
}
for i := 0; i < len(docs); i++ {
doc := document.NewDocument(strconv.Itoa(docs[i].field2))
doc.Fields = []document.Field{
document.NewTextField("field1", []uint64{}, []byte(docs[i].field1)),
document.NewNumericField("field2", []uint64{}, float64(docs[i].field2)),
}
doc.CompositeFields = []*document.CompositeField{
document.NewCompositeFieldWithIndexingOptions(
"_all", true, []string{"field1"}, []string{},
index.IndexField|index.IncludeTermVectors),
}
if err = batch.IndexAdvanced(doc); err != nil {
t.Error(err)
}
}
if err = idx.Batch(batch); err != nil {
t.Error(err)
}
/*
Query:
DISJ
/ \
CONJ TERM(two)
/
TERM(one)
*/
tq1 := bleve.NewTermQuery("one")
tq1.SetBoost(2)
tq2 := bleve.NewTermQuery("two")
tq2.SetBoost(3)
cq := bleve.NewConjunctionQuery(tq1)
cq.SetBoost(4)
q := bleve.NewDisjunctionQuery(tq1, tq2)
sr := bleve.NewSearchRequestOptions(q, 2, 0, true)
res, err := idx.Search(sr)
if err != nil {
t.Error(err)
}
if len(res.Hits) != 2 {
t.Errorf("indexType: %s Expected 2 hits, but got: %v", indexName, len(res.Hits))
}
return res.Hits
}

519
test/versus_test.go Normal file
View File

@@ -0,0 +1,519 @@
// Copyright (c) 2014 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 test
import (
"bytes"
"encoding/json"
"fmt"
"math"
"math/rand"
"os"
"reflect"
"strconv"
"strings"
"testing"
"text/template"
"time"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/index/scorch"
"github.com/blevesearch/bleve/v2/index/upsidedown"
"github.com/blevesearch/bleve/v2/index/upsidedown/store/boltdb"
"github.com/blevesearch/bleve/v2/mapping"
"github.com/blevesearch/bleve/v2/search"
)
// Tests scorch indexer versus upsidedown/bolt indexer against various
// templated queries. Example usage from the bleve top-level directory...
//
// go test -v -run TestScorchVersusUpsideDownBolt ./test
// VERBOSE=1 FOCUS=Trista go test -v -run TestScorchVersusUpsideDownBolt ./test
//
func init() {
// override for tests
scorch.DefaultPersisterNapTimeMSec = 1
}
func TestScorchVersusUpsideDownBoltAll(t *testing.T) {
(&VersusTest{
t: t,
NumDocs: 1000,
MaxWordsPerDoc: 20,
NumWords: 10,
BatchSize: 1000,
NumAttemptsPerSearch: 100,
}).run(scorch.Name, boltdb.Name, upsidedown.Name, boltdb.Name, nil, nil)
}
func TestScorchVersusUpsideDownBoltSmallMNSAM(t *testing.T) {
(&VersusTest{
t: t,
Focus: "must-not-same-as-must",
NumDocs: 5,
MaxWordsPerDoc: 2,
NumWords: 1,
BatchSize: 1,
NumAttemptsPerSearch: 1,
}).run(scorch.Name, boltdb.Name, upsidedown.Name, boltdb.Name, nil, nil)
}
func TestScorchVersusUpsideDownBoltSmallCMP11(t *testing.T) {
(&VersusTest{
t: t,
Focus: "conjuncts-match-phrase-1-1",
NumDocs: 30,
MaxWordsPerDoc: 8,
NumWords: 2,
BatchSize: 1,
NumAttemptsPerSearch: 1,
}).run(scorch.Name, boltdb.Name, upsidedown.Name, boltdb.Name, nil, nil)
}
// -------------------------------------------------------
// Templates used to compare search results in the "versus" tests.
var testVersusSearchTemplates = []string{
`{
"about": "expected to return zero hits",
"query": {
"query": "title:notARealTitle"
}
}`,
`{
"about": "try straight word()'s",
"query": {
"query": "body:{{word}}"
}
}`,
`{
"about": "conjuncts on same term",
"query": {
"conjuncts": [
{ "field": "body", "term": "{{word}}", "boost": 1.0 },
{ "field": "body", "term": "{{word}}", "boost": 1.0 }
]
}
}`,
`{
"about": "disjuncts on same term",
"query": {
"disjuncts": [
{ "field": "body", "term": "{{word}}", "boost": 1.0 },
{ "field": "body", "term": "{{word}}", "boost": 1.0 }
]
}
}`,
`{
"about": "never-matching-title-conjuncts",
"query": {
"conjuncts": [
{"field": "body", "match": "{{word}}"},
{"field": "body", "match": "{{word}}"},
{"field": "title", "match": "notAnActualTitle"}
]
}
}`,
`{
"about": "never-matching-title-disjuncts",
"query": {
"disjuncts": [
{"field": "body", "match": "{{word}}"},
{"field": "body", "match": "{{word}}"},
{"field": "title", "match": "notAnActualTitle"}
]
}
}`,
`{
"about": "must-not-never-matches",
"query": {
"must_not": {"disjuncts": [
{"field": "title", "match": "notAnActualTitle"}
]},
"should": {"disjuncts": [
{"field": "body", "match": "{{word}}"}
]}
}
}`,
`{
"about": "must-not-only",
"query": {
"must_not": {"disjuncts": [
{"field": "body", "term": "{{word}}"}
]}
}
}`,
`{
"about": "must-not-same-as-must -- see: MB-27291",
"query": {
"must_not": {"disjuncts": [
{"field": "body", "match": "{{word}}"}
]},
"must": {"conjuncts": [
{"field": "body", "match": "{{word}}"}
]}
}
}`,
`{
"about": "must-not-same-as-should",
"query": {
"must_not": {"disjuncts": [
{"field": "body", "match": "{{word}}"}
]},
"should": {"disjuncts": [
{"field": "body", "match": "{{word}}"}
]}
}
}`,
`{
"about": "inspired by testrunner RQG issue -- see: MB-27291",
"query": {
"must_not": {"disjuncts": [
{"field": "title", "match": "Trista Allen"},
{"field": "body", "match": "{{word}}"}
]},
"should": {"disjuncts": [
{"field": "title", "match": "Kallie Safiya Amara"},
{"field": "body", "match": "{{word}}"}
]}
}
}`,
`{
"about": "conjuncts-match-phrase-1-1 inspired by testrunner RQG issue -- see: MB-27291",
"query": {
"conjuncts": [
{"field": "body", "match": "{{bodyWord 0}}"},
{"field": "body", "match_phrase": "{{bodyWord 1}} {{bodyWord 1}}"}
]
}
}`,
`{
"about": "conjuncts-match-phrase-1-2 inspired by testrunner RQG issue -- see: MB-27291 -- FAILS!!",
"query": {
"conjuncts": [
{"field": "body", "match": "{{bodyWord 0}}"},
{"field": "body", "match_phrase": "{{bodyWord 1}} {{bodyWord 2}}"}
]
}
}`,
}
// -------------------------------------------------------
type VersusTest struct {
t *testing.T
// Use environment variable VERBOSE=<integer> that's > 0 for more
// verbose output.
Verbose int
// Allow user to focus on particular search templates, where
// where the search template must contain the Focus string.
Focus string
NumDocs int // Number of docs to insert.
MaxWordsPerDoc int // Max number words in each doc's Body field.
NumWords int // Total number of words in the dictionary.
BatchSize int // Batch size when inserting docs.
NumAttemptsPerSearch int // For each search template, number of searches to try.
// The Bodies is an array with length NumDocs, where each entry
// is the words in a doc's Body field.
Bodies [][]string
CurAttempt int
TotAttempts int
}
// -------------------------------------------------------
func testVersusSearches(vt *VersusTest, searchTemplates []string, idxA, idxB bleve.Index) {
t := vt.t
funcMap := template.FuncMap{
// Returns a word. The word may or may not be in any
// document's body.
"word": func() string {
return vt.genWord(vt.CurAttempt % vt.NumWords)
},
// Picks a document and returns the i'th word in that
// document's body. You can use this in searches to
// definitely find at least one document.
"bodyWord": func(i int) string {
body := vt.Bodies[vt.CurAttempt%len(vt.Bodies)]
if len(body) == 0 {
return ""
}
return body[i%len(body)]
},
}
// Optionally allow call to focus on a particular search templates,
// where the search template must contain the vt.Focus string.
if vt.Focus == "" {
vt.Focus = os.Getenv("FOCUS")
}
for i, searchTemplate := range searchTemplates {
if vt.Focus != "" && !strings.Contains(searchTemplate, vt.Focus) {
continue
}
tmpl, err := template.New("search").Funcs(funcMap).Parse(searchTemplate)
if err != nil {
t.Fatalf("could not parse search template: %s, err: %v", searchTemplate, err)
}
for j := 0; j < vt.NumAttemptsPerSearch; j++ {
vt.CurAttempt = j
var buf bytes.Buffer
err = tmpl.Execute(&buf, vt)
if err != nil {
t.Fatalf("could not execute search template: %s, err: %v", searchTemplate, err)
}
bufBytes := buf.Bytes()
if vt.Verbose > 0 {
fmt.Printf(" %s\n", bufBytes)
}
var search bleve.SearchRequest
err = json.Unmarshal(bufBytes, &search)
if err != nil {
t.Fatalf("could not unmarshal search: %s, err: %v", bufBytes, err)
}
search.Size = vt.NumDocs * 10 // Crank up limit to get all results.
searchA := search
searchB := search
resA, errA := idxA.Search(&searchA)
resB, errB := idxB.Search(&searchB)
if errA != errB {
t.Errorf("search: (%d) %s,\n err mismatch, errA: %v, errB: %v",
i, bufBytes, errA, errB)
}
// Scores might have float64 vs float32 wobbles, so truncate precision.
resA.MaxScore = math.Trunc(resA.MaxScore*1000.0) / 1000.0
resB.MaxScore = math.Trunc(resB.MaxScore*1000.0) / 1000.0
// Timings may be different between A & B, so force equality.
resA.Took = resB.Took
// Hits might have different ordering since some indexers
// (like upsidedown) have a natural secondary sort on id
// while others (like scorch) don't. So, we compare by
// putting the hits from A & B into maps.
hitsA := hitsById(resA)
hitsB := hitsById(resB)
for id, hitA := range hitsA {
hitB := hitsB[id]
if len(hitA.FieldTermLocations) == 0 {
hitA.FieldTermLocations = nil
}
if len(hitB.FieldTermLocations) == 0 {
hitB.FieldTermLocations = nil
}
if !reflect.DeepEqual(hitA, hitB) {
t.Errorf("\n driving from hitsA\n hitA: %#v,\n hitB: %#v", hitA, hitB)
idx, _ := strconv.Atoi(id)
t.Errorf("\n doc: %d, body: %s", idx, strings.Join(vt.Bodies[idx], " "))
}
}
for id, hitB := range hitsB {
hitA := hitsA[id]
if len(hitA.FieldTermLocations) == 0 {
hitA.FieldTermLocations = nil
}
if len(hitB.FieldTermLocations) == 0 {
hitB.FieldTermLocations = nil
}
if !reflect.DeepEqual(hitA, hitB) {
t.Errorf("\n driving from hitsB\n hitA: %#v,\n hitB: %#v", hitA, hitB)
idx, _ := strconv.Atoi(id)
t.Errorf("\n doc: %d, body: %s", idx, strings.Join(vt.Bodies[idx], " "))
}
}
if !reflect.DeepEqual(hitsA, hitsB) {
t.Errorf("=========\nsearch: (%d) %s,\n res hits mismatch,\n len(hitsA): %d,\n len(hitsB): %d",
i, bufBytes, len(hitsA), len(hitsB))
t.Errorf("\n hitsA: %#v,\n hitsB: %#v",
hitsA, hitsB)
}
resA.Hits = nil
resB.Hits = nil
resA.Cost = 0
resB.Cost = 0
if !reflect.DeepEqual(resA, resB) {
resAj, _ := json.Marshal(resA)
resBj, _ := json.Marshal(resB)
t.Errorf("search: (%d) %s,\n res mismatch,\n resA: %s,\n resB: %s",
i, bufBytes, resAj, resBj)
}
if vt.Verbose > 0 {
fmt.Printf(" Total: (%t) %d\n", resA.Total == resB.Total, resA.Total)
}
vt.TotAttempts++
}
}
}
// Organizes the hits into a map keyed by id.
func hitsById(res *bleve.SearchResult) map[string]*search.DocumentMatch {
rv := make(map[string]*search.DocumentMatch, len(res.Hits))
for _, hit := range res.Hits {
// Clear out or truncate precision of hit fields that might be
// different across different indexer implementations.
hit.Index = ""
hit.Score = math.Trunc(hit.Score*1000.0) / 1000.0
hit.IndexInternalID = nil
hit.HitNumber = 0
rv[hit.ID] = hit
}
return rv
}
// -------------------------------------------------------
func (vt *VersusTest) run(indexTypeA, kvStoreA, indexTypeB, kvStoreB string,
cb func(versusTest *VersusTest, searchTemplates []string, idxA, idxB bleve.Index),
searchTemplates []string,
) {
if cb == nil {
cb = testVersusSearches
}
if searchTemplates == nil {
searchTemplates = testVersusSearchTemplates
}
if vt.Verbose <= 0 {
vt.Verbose, _ = strconv.Atoi(os.Getenv("VERBOSE"))
}
dirA := "/tmp/bleve-versus-test-a"
dirB := "/tmp/bleve-versus-test-b"
defer func() {
_ = os.RemoveAll(dirA)
_ = os.RemoveAll(dirB)
}()
_ = os.RemoveAll(dirA)
_ = os.RemoveAll(dirB)
imA := vt.makeIndexMapping()
imB := vt.makeIndexMapping()
kvConfigA := map[string]interface{}{}
kvConfigB := map[string]interface{}{}
idxA, err := bleve.NewUsing(dirA, imA, indexTypeA, kvStoreA, kvConfigA)
if err != nil || idxA == nil {
vt.t.Fatalf("new using err: %v", err)
}
defer func() { _ = idxA.Close() }()
idxB, err := bleve.NewUsing(dirB, imB, indexTypeB, kvStoreB, kvConfigB)
if err != nil || idxB == nil {
vt.t.Fatalf("new using err: %v", err)
}
defer func() { _ = idxB.Close() }()
if vt.Bodies == nil {
vt.Bodies = vt.genBodies()
}
vt.insertBodies(idxA)
vt.insertBodies(idxB)
cb(vt, searchTemplates, idxA, idxB)
}
// -------------------------------------------------------
func (vt *VersusTest) makeIndexMapping() mapping.IndexMapping {
standardFM := bleve.NewTextFieldMapping()
standardFM.Store = false
standardFM.IncludeInAll = false
standardFM.IncludeTermVectors = true
standardFM.Analyzer = "standard"
dm := bleve.NewDocumentMapping()
dm.AddFieldMappingsAt("title", standardFM)
dm.AddFieldMappingsAt("body", standardFM)
im := bleve.NewIndexMapping()
im.DefaultMapping = dm
im.DefaultAnalyzer = "standard"
return im
}
func (vt *VersusTest) insertBodies(idx bleve.Index) {
batch := idx.NewBatch()
for i, bodyWords := range vt.Bodies {
title := fmt.Sprintf("%d", i)
body := strings.Join(bodyWords, " ")
err := batch.Index(title, map[string]interface{}{"title": title, "body": body})
if err != nil {
vt.t.Fatalf("batch.Index err: %v", err)
}
if i%vt.BatchSize == 0 {
err = idx.Batch(batch)
if err != nil {
vt.t.Fatalf("batch err: %v", err)
}
batch.Reset()
}
}
err := idx.Batch(batch)
if err != nil {
vt.t.Fatalf("last batch err: %v", err)
}
}
func (vt *VersusTest) genBodies() (rv [][]string) {
for i := 0; i < vt.NumDocs; i++ {
rv = append(rv, vt.genBody())
}
return rv
}
func (vt *VersusTest) genBody() (rv []string) {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
m := rng.Intn(vt.MaxWordsPerDoc)
for j := 0; j < m; j++ {
rv = append(rv, vt.genWord(rng.Intn(vt.NumWords)))
}
return rv
}
func (vt *VersusTest) genWord(i int) string {
return fmt.Sprintf("%x", i)
}