///|
/// Stable identifier for a field within a MoonSearch schema.
///
/// M0 constructs field identifiers directly. A schema builder will own their
/// allocation in a later milestone.
pub(all) struct FieldId {
value : Int
} derive(Eq, @debug.Debug)
///|
pub fn FieldId::new(value : Int) -> FieldId {
{ value, }
}
///|
/// Segment-local document identifier.
pub(all) struct DocId {
value : Int
} derive(Eq, @debug.Debug)
///|
pub fn DocId::new(value : Int) -> DocId {
{ value, }
}
///|
/// Address of a document in a searcher's segment set.
///
/// M1 searchers contain one segment, so `segment_ord` is always zero. Keeping
/// the segment ordinal in the public result model avoids treating a
/// segment-local `DocId` as a global identifier when multi-segment search is
/// added later.
pub(all) struct DocAddress {
segment_ord : Int
doc_id : DocId
} derive(Eq, @debug.Debug)
///|
pub fn DocAddress::new(segment_ord : Int, doc_id : DocId) -> DocAddress {
{ segment_ord, doc_id }
}
///|
/// A document containing zero or more text fields.
pub struct Document {
field_ids : Array[FieldId]
texts : Array[String]
}
///|
pub fn Document::new() -> Document {
{ field_ids: [], texts: [] }
}
///|
/// Adds one text value to the document.
pub fn Document::add_text(
self : Document,
field_id : FieldId,
text : String,
) -> Unit {
self.field_ids.push(field_id)
self.texts.push(text)
}
///|
pub fn Document::field_count(self : Document) -> Int {
self.field_ids.length()
}
///|
pub fn Document::field_id_at(self : Document, index : Int) -> FieldId? {
if index < 0 || index >= self.field_ids.length() {
None
} else {
Some(self.field_ids[index])
}
}
///|
pub fn Document::text_at(self : Document, index : Int) -> String? {
if index < 0 || index >= self.texts.length() {
None
} else {
Some(self.texts[index])
}
}
///|
/// Immutable snapshot of the text values stored for one indexed document.
pub struct StoredDocument {
field_ids : ReadOnlyArray[FieldId]
texts : ReadOnlyArray[String]
}
///|
pub fn Document::snapshot(self : Document) -> StoredDocument {
let field_ids : Array[FieldId] = []
let texts : Array[String] = []
for field_id in self.field_ids {
field_ids.push(field_id)
}
for text in self.texts {
texts.push(text)
}
{
field_ids: ReadOnlyArray::from_array(field_ids),
texts: ReadOnlyArray::from_array(texts),
}
}
///|
pub fn StoredDocument::from_fields(
field_ids : Array[FieldId],
texts : Array[String],
) -> StoredDocument {
guard field_ids.length() == texts.length() else {
abort("stored field identifiers and texts must have equal length")
}
{
field_ids: ReadOnlyArray::from_array(field_ids),
texts: ReadOnlyArray::from_array(texts),
}
}
///|
/// Returns every stored text value for a field in insertion order.
pub fn StoredDocument::texts_for(
self : StoredDocument,
field_id : FieldId,
) -> ReadOnlyArray[String] {
let values : Array[String] = []
for index in 0.. Term {
{ field_id, text }
}