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

103
search/collector/nested.go Normal file
View File

@@ -0,0 +1,103 @@
// Copyright (c) 2026 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 collector
import (
"github.com/blevesearch/bleve/v2/search"
index "github.com/blevesearch/bleve_index_api"
)
type collectStoreNested struct {
// descAdder is used to customize how descendants are merged into their parent
descAdder search.DescendantAdderCallbackFn
// nested reader to retrieve ancestor information
nr index.NestedReader
// the current root document match being built
currRoot *search.DocumentMatch
// the ancestor ID of the current root document being built
currRootAncestorID index.AncestorID
// prealloc slice for ancestor IDs
ancestors []index.AncestorID
}
func newStoreNested(nr index.NestedReader, descAdder search.DescendantAdderCallbackFn) *collectStoreNested {
rv := &collectStoreNested{
descAdder: descAdder,
nr: nr,
}
return rv
}
// ProcessNestedDocument adds a document to the nested store, merging it into its root document
// as needed. If the returned DocumentMatch is nil, the incoming doc has been merged
// into its parent and should not be processed further. If the returned DocumentMatch
// is non-nil, it represents a complete root document that should be processed further.
// NOTE: This implementation assumes that documents are added in increasing order of their internal IDs
// which is guaranteed by all searchers in bleve.
func (c *collectStoreNested) ProcessNestedDocument(ctx *search.SearchContext, doc *search.DocumentMatch) (*search.DocumentMatch, error) {
// find ancestors for the doc
var err error
c.ancestors, err = c.nr.Ancestors(doc.IndexInternalID, c.ancestors[:0])
if err != nil {
return nil, err
}
if len(c.ancestors) == 0 {
// should not happen, every doc should have at least itself as ancestor
return nil, nil
}
// root docID is the last ancestor
rootID := c.ancestors[len(c.ancestors)-1]
// check if there is an interim root already and if the incoming doc belongs to it
if c.currRoot != nil && c.currRootAncestorID.Equals(rootID) {
// there is an interim root already, and the incoming doc belongs to it
if err := c.descAdder(c.currRoot, doc); err != nil {
return nil, err
}
// recycle the child document now that it's merged into the interim root
ctx.DocumentMatchPool.Put(doc)
return nil, nil
}
// completedRoot is the root document match to return, if any
var completedRoot *search.DocumentMatch
if c.currRoot != nil {
// we have an existing interim root, return it for processing
completedRoot = c.currRoot
}
// no interim root for now so either we have a root document incoming
// or we have a child doc and need to create an interim root
if len(c.ancestors) == 1 {
// incoming doc is the root itself
c.currRoot = doc
c.currRootAncestorID = rootID
return completedRoot, nil
}
// this is a child doc, create interim root
newDM := ctx.DocumentMatchPool.Get()
newDM.IndexInternalID = rootID.ToIndexInternalID(newDM.IndexInternalID)
// merge the incoming doc into the new interim root
c.currRoot = newDM
c.currRootAncestorID = rootID
if err := c.descAdder(c.currRoot, doc); err != nil {
return nil, err
}
// recycle the child document now that it's merged into the interim root
ctx.DocumentMatchPool.Put(doc)
return completedRoot, nil
}
// Current returns the current interim root document match being built, if any
func (c *collectStoreNested) Current() *search.DocumentMatch {
return c.currRoot
}