Šķîþ ţö ḿàîñ çöñţéñţ

Çöñţéñţ Ḿéḿöŕý Ḿàţçĥîñĝ Àļĝöŕîţĥḿ

Ţĥîš ñöţé þŕöṽîđéš îḿþļéḿéñţàţîöñ đéţàîļš ƒöŕ Ç-09.

Đéŕîṽéđ ḿàţçĥîñĝ ķéýš

Éàçĥ çöñţéñţ-ḿéḿöŕý éñţŕý šţöŕéš îţš ṽàŕîàñţš àš []model.Run šéǫüéñçéš (Ƒ-02). Šéṽéŕàļ ḿàţçĥîñĝ ŕéþŕéšéñţàţîöñš àŕé đéŕîṽéđ ƒŕöḿ ţĥöšé ŕüñš àţ šţöŕàĝé ţîḿé àñđ îñđéẋéđ ƒöŕ ƒàšţ ļööķüþ. Ţĥé memory þàçķàĝé çöḿþüţéš ţĥéḿ ŵîţĥ ţĥé ƒŕàḿéŵöŕķ'š þŕöĵéçţîöñ ĥéļþéŕš îñ core/model:

  • þļàîñ: model.FlattenRuns(runs) (ñöŕḿàļîžéđ ṽîà NormalizeText). Ķééþš Text ŕüñš ṽéŕƃàţîḿ, ŕéñđéŕš Ph þļàçéĥöļđéŕš àš \{equiv\} àñđ Sub ŕüñš àš [equiv], éḿîţš þàîŕéđ-çöđé (PcOpen/PcClose) îññéŕ çöñţéñţ ƃüţ ñöţ ţĥé ŵŕàþþéŕš, àñđ ţàķéš ţĥé 'öţĥéŕ' ƃŕàñçĥ öƒ þļüŕàļ/šéļéçţ çöñšţŕüçţš (öŕ ţĥé ƒîŕšţ ƒöŕḿ îƒ 'öţĥéŕ' îš àƃšéñţ). Éñàƃļéš ḿàţçĥîñĝ àĝàîñšţ þļàîñ-ţéẋţ ḿéḿöŕîéš îḿþöŕţéđ ƒŕöḿ öţĥéŕ ţööļš, àñđ àĝàîñšţ üñàñàļýžéđ çöñţéñţ.
  • šţŕüçţüŕàļ: model.RunsStructuralText(runs). Ŕéñđéŕš îñļîñé-çöđé ŕüñš àš þöšîţîöñàļ þļàçéĥöļđéŕš: PcOpen àš \{1\}, PcClose àš \{/1\}, àñđ Ph àš \{1/\}. Éñàƃļéš ḿàţçĥîñĝ ŵîţĥ îñļîñé-çöđé þöšîţîöñ àŵàŕéñéšš.
  • ĝéñéŕàļîžéđ: model.RunsGeneralizedText(runs). Ŕéñđéŕš éñţîţý Ph ŕüñš (ŵĥöšé Type îš àñ éñţîţý ţýþé) àš ţýþéđ þļàçéĥöļđéŕš (\{PERSON\}, \{PRODUCT\}) àñđ öţĥéŕ îñļîñé-çöđé ŕüñš àš îñ ţĥé šţŕüçţüŕàļ ķéý. Ḿàẋîḿüḿ ŕéüšé: éñţîţîéš àŕé îñţéŕçĥàñĝéàƃļé.

Ţĥé ĝéñéŕàļîžéđ ķéý ŕéüšéš ţĥé ḿöšţ: "Ĵöĥñ ŵöŕķš àţ Àçḿé" àñđ "Àļîçé ŵöŕķš àţ Ĝļöƃéẋ" ƃöţĥ ĝéñéŕàļîžé ţö \{PERSON\} works at \{ORGANIZATION\}, àñ éẋàçţ ḿàţçĥ.

Ţîéŕéđ Ḿàţçĥîñĝ Þîþéļîñé

Ļööķüþ ţŕîéš ḿàţçĥîñĝ šţŕàţéĝîéš îñ öŕđéŕ öƒ ŕéüšé þöţéñţîàļ:

  1. ĝéñéŕàļîžéđ éẋàçţ: šçöŕé 1.0 (éñţîţîéš đéŕ, šţŕüçţüŕé îđéñţîçàļ)
  2. šţŕüçţüŕàļ éẋàçţ: šçöŕé 1.0 (îñļîñé çöđéš ḿàţçĥ éẋàçţļý)
  3. þļàîñ éẋàçţ: šçöŕé 1.0 öñļý ŵĥéñ ţĥé šţŕüçţüŕàļ ķéý àļšö ḿàţçĥéš; ţéẋţ-öñļý éǫüàļîţý àçŕöšš đéŕîñĝ îñļîñé-çöđé šţŕüçţüŕé çàþš àţ ScoreNearExact (0.99, ţàĝ-ḿîšḿàţçĥ þéñàļţý)
  4. ĝéñéŕàļîžéđ ƒüžžý: Ļéṽéñšĥţéîñ öñ ĝéñéŕàļîžéđ ķéýš
  5. šţŕüçţüŕàļ ƒüžžý: Ļéṽéñšĥţéîñ öñ šţŕüçţüŕàļ ķéýš
  6. þļàîñ ƒüžžý: Ļéṽéñšĥţéîñ öñ þļàîñ ķéýš

Àƒţéŕ ţĥé éẋàçţ ţîéŕš, ḿüļţîþļé ƒüļļ-šçöŕé ḿàţçĥéš ŵîţĥ đéŕîñĝ ţàŕĝéţ ţéẋţš àŕé šéţţļéđ ƃý ŵĥéŕé éàçĥ àñšŵéŕ ŵàš àþþŕöṽéđ. LookupOptions.Point ñàḿéš ţĥé þöîñţ ţĥé çàļļéŕ îš àšķîñĝ ƒŕöḿ; éàçĥ éñţŕý çàŕŕîéš ţĥé þöîñţ îţš àñšŵéŕ ŵàš àþþŕöṽéđ àţ (Entry.Point, ţĥé point çöļüḿñ öñ tm_entries, ŠǪĻîţé ḿîĝŕàţîöñ ṽ4). memory.PointDistance çöḿþàŕéš ţĥé ţŵö àš à þŕéƒîẋ ŵàļķ đöŵñ profile → channel → collection, àñđ ţĥé ñéàŕéšţ àñšŵéŕ ķééþš šçöŕé 1.0 ŵĥîļé ţĥé ŕéšţ đéḿöţé ţö ScoreNearExact. À ţîé (ţŵö àþþŕöṽàļš àţ öñé þöîñţ, öŕ ţŵö éǫüàļļý ƒàŕ) ĝöéš ţö ţĥé šḿàļļéŕ ţàŕĝéţ ţéẋţ (memory.NearerAnswer).

À çàļļéŕ ţĥàţ ñàḿéš ñö þöîñţ šéţţļéš ñöţĥîñĝ: ţĥé àḿƃîĝüîţý ŕüļé ŕüñš îñšţéàđ àñđ éṽéŕý ƒüļļ-šçöŕé ḿàţçĥ đéḿöţéš ţö ScoreNearExact ŵîţĥ Match.Ambiguous šéţ, šö éẋàçţ-öñļý çöñšüḿéŕš (éẋţŕàçţ þŕé-ƒîļļ, fillTargetThreshold: 100) šķîþ ţĥéḿ ŕàţĥéŕ ţĥàñ þîçķîñĝ ƃý šţöŕàĝé öŕđéŕ. Ŕéšüļţš öŕđéŕ đéţéŕḿîñîšţîçàļļý ƃý (šçöŕé đéšç, ḿàţçĥ-ţýþé þŕîöŕîţý, éñţŕý ÎĐ).

Ţĥé ƒîŕšţ ḿàţçĥ àţ öŕ àƃöṽé ţĥé šçöŕé ţĥŕéšĥöļđ ŵîñš. À ĝéñéŕàļîžéđ éẋàçţ ḿàţçĥ (đéŕéñţ éñţîţý ṽàļüéš, îđéñţîçàļ šţŕüçţüŕé) îš þŕéƒéŕŕéđ öṽéŕ à þļàîñ ƒüžžý ḿàţçĥ (šîḿîļàŕ ţéẋţ, üñķñöŵñ šţŕüçţüŕé). Ļéṽéñšĥţéîñ éđîţ đîšţàñçé ŵîţĥ à çöñƒîĝüŕàƃļé ţĥŕéšĥöļđ þŕöṽîđéš ƒüžžý ḿàţçĥîñĝ; ţĥé recycle ţööļ ļööķš üþ àţ fuzzyThreshold (đéƒàüļţ 70) àñđ ƒîļļš àţ fillTargetThreshold (đéƒàüļţ 95), ŕéçöŕđîñĝ ḿàţçĥéš ƃéţŵééñ ţĥé ţŵö àš àļţéŕñàţîṽé-ţŕàñšļàţîöñ çàñđîđàţéš.

Éñţîţý Àđàþţàţîöñ

Ŵĥéñ à ĝéñéŕàļîžéđ ḿàţçĥ îš ƒöüñđ, ţĥé ḿàţçĥ ŕéšüļţ çàŕŕîéš àđàþţàţîöñ îñƒöŕḿàţîöñ ţö šüƃšţîţüţé éñţîţý ṽàļüéš ƒŕöḿ ţĥé çüŕŕéñţ šöüŕçé îñţö ţĥé šţöŕéđ ţàŕĝéţ:

type Match struct {
Entry Entry
Score float64 // 0.0-1.0 (1.0 = exact match, text AND structure)
MatchType MatchType
ProjectID string // provenance: project ID of the matched entry
Ambiguous bool // an exact match demoted because no point was named
EntityAdaptations []EntityAdaptation
}

Ţĥé recycle ţööļ (É-03) àþþļîéš àđàþţàţîöñš àüţöḿàţîçàļļý; ţŕàñšļàţöŕš ŕéçéîṽé þŕé-àđàþţéđ ţàŕĝéţš ŵîţĥ çöŕŕéçţ éñţîţý ṽàļüéš.

Ṽéŕšîöñ çĥàîñš

Àñ éñţŕý çàŕŕîéš Unit, ţĥé đüŕàƃļé ƃļöçķ îđéñţîţý îţ ŵàš àþþŕöṽéđ ƒöŕ (ţĥé unit çöļüḿñ öñ tm_entries, ŠǪĻîţé ḿîĝŕàţîöñ ṽ5; éḿþţý ƒöŕ à šééđ, àñ îḿþöŕţ, öŕ àñ éñţŕý ŵŕîţţéñ ƃéƒöŕé ţĥé çöļüḿñ éẋîšţéđ, àñđ ñéṽéŕ ƃàçķƒîļļéđ). À ƃļöçķ ŵĥöšé šöüŕçé îš ŕéŵŕîţţéñ ŵŕîţéš à ñéŵ éñţŕý ƃéšîđé ţĥé öļđ öñé, àñđ Unit îš ŵĥàţ ŕéļàţéš ţĥéḿ.

memory.VersionReader îš ţĥé öþţîöñàļ çàþàƃîļîţý öƒ ŕéţüŕñîñĝ à ƃļöçķ'š þŕîöŕ àñšŵéŕš; ƃöţĥ ţĥé îñ-ḿéḿöŕý àñđ ţĥé ŠǪĻîţé ƃàçķéñđš îḿþļéḿéñţ îţ:

type VersionQuery struct {
Unit string // required
Point string // narrow to one point; empty = every point the block has sat at
Limit int // newest first; zero = DefaultVersionLimit (10)
}

type Version struct {
Entry Entry
ContextFingerprint string // from the entry's most recent origin; empty if ungoverned
}

Versions(ctx, q VersionQuery, excludeID string) ([]Version, error)

Version.GovernedBy(fingerprint) îš ţŕüé öñļý ŵĥéñ ƃöţĥ ƒîñĝéŕþŕîñţš àŕé ñöñ-éḿþţý àñđ éǫüàļ. memory/leverage.PriorVersionFor ŵàļķš ţĥé çĥàîñ ŵîţĥ Limit: 1, àþþļîéš ţĥàţ ĝàţé, àñđ ŕéţüŕñš ţĥé šöüŕçé àñđ ţàŕĝéţ ţéẋţš öƒ ţĥé þŕîöŕ àñšŵéŕ, öŕ ñöţĥîñĝ.

Ţĥé þŕöđüçéŕ-ƒàçîñĝ çöñţŕàçţ îš core/memory.Provider (Lookup(ctx, Request) àñđ PriorVersion(ctx, VersionRequest)), îḿþļéḿéñţéđ ƃý memory/leverage.Provider öṽéŕ àñý memory.ContentMemory. À šţöŕé ţĥàţ đöéš ñöţ îḿþļéḿéñţ VersionReader àñšŵéŕš PriorVersion ŵîţĥ ƒàļšé. Ţĥé .kmb ƃüñđļé ƒöŕḿàţ çàŕŕîéš point àñđ unit þéŕ éñţŕý šö à šééđ ŕöüñđ-ţŕîþš îţš çĥàîñ.

Ƒüžžý Çàñđîđàţé Ŕéţŕîéṽàļ

Ţîéŕš 4-6 (ƒüžžý ḿàţçĥîñĝ) üšé ţŕîĝŕàḿ-ƃàšéđ çàñđîđàţé ŕéţŕîéṽàļ, ŵĥîçĥ ŕéđüçéš 100Ķ éñţŕîéš ţö ~200 çàñđîđàţéš ƃéƒöŕé Ļéṽéñšĥţéîñ šçöŕîñĝ. Šçöŕîñĝ éṽéŕý éñţŕý îñ à ļöçàļé þàîŕ îñšţéàđ ŵöüļđ ƃé àñ Ö(ñ) ƒüļļ ţàƃļé šçàñ.

Üñîçöđé ÑƑÇ Ñöŕḿàļîžàţîöñ

NormalizeText() àþþļîéš Üñîçöđé ÑƑÇ ñöŕḿàļîžàţîöñ (golang.org/x/text/unicode/norm) ƃéƒöŕé ŵĥîţéšþàçé ñöŕḿàļîžàţîöñ. Ţĥîš ƒîẋéš ŕéàļ éđĝé çàšéš: Àŕàƃîç đîàçŕîţîçš (ţàšĥķééļ) àš šéþàŕàţé çĥàŕàçţéŕš ṽš. çöḿƃîñéđ, Ĥàñĝüļ ĵàḿö ṽš. çöḿþöšéđ šýļļàƃļéš, àñđ àççéñţéđ Ļàţîñ (é + çöḿƃîñîñĝ àçüţé ṽš. é).

ŠǪĻîţé: ƑŢŠ5 Ţŕîĝŕàḿ Ţöķéñîžéŕ

Ţŵö ƑŢŠ5 ṽîŕţüàļ ţàƃļéš ƃàçķéđ ƃý ţĥé tm_variants ţàƃļé, ķéþţ îñ šýñç öñ ŵŕîţé:

  • tm_variant_trigram: tokenize='trigram' öñ plain, struct_key, general_key. Üšéđ ƒöŕ ƒüžžý çàñđîđàţé ŕéţŕîéṽàļ.
  • tm_variant_search: ŵöŕđ ţöķéñîžéŕ ṽîà storage.FTSWordTokenizer öñ text. Ŕéšöļṽéš ţö icu üñđéŕ çĝö ƃüîļđš àñđ unicode61 üñđéŕ ţĥé đéƒàüļţ þüŕé-Ĝö (ḿöđéŕñç, ñö-çĝö) àñđ ŵàšḿ ƃüîļđš; ţĥé ÎÇÜ ţöķéñîžéŕ îš à çĝö-öñļý ƑŢŠ5 éẋţéñšîöñ. Üšéđ ƒöŕ ŕàñķéđ ÜÎ šéàŕçĥ (ƑŢŠ5 ƂḾ25).

BuildTrigramQuery() çöñšţŕüçţš ţĥé ƑŢŠ5 ḾÀŢÇĤ éẋþŕéššîöñ:

  • Ḿüļţî-ŵöŕđ ţéẋţ (Ļàţîñ, éţç.): ÖŔ öƒ îñđîṽîđüàļ ŵöŕđš ≥3 çĥàŕš àš ǫüöţéđ šüƃšţŕîñĝš.
  • Šîñĝļé ŵöŕđ / ÇĴĶ: Öṽéŕļàþþîñĝ 4-çĥàŕàçţéŕ ŵîñđöŵš šàḿþļéđ àţ éṽéñ îñţéŕṽàļš (ḿàẋ 6 ŵîñđöŵš).

Ƒàļļš ƃàçķ ţö ļéñĝţĥ-ƃàšéđ þŕé-ƒîļţéŕîñĝ (LENGTH(plain) BETWEEN min AND max) îƒ ƑŢŠ5 ţŕîĝŕàḿ îš üñàṽàîļàƃļé àţ ŕüñţîḿé.

À šéçöñđ ŠǪĻ đîàļéçţ

Ţĥé memory/schema þàçķàĝé đéçļàŕéš ţĥé ţàƃļéš öñçé àñđ éḿîţš ţĥéḿ îñ ţŵö đîàļéçţš. Ƃéšîđé ţĥé ŠǪĻîţé đéƒîñîţîöñš îţ çàŕŕîéš à šéçöñđ ŠǪĻ đîàļéçţ ŵĥöšé éǫüîṽàļéñţš öƒ ţĥé ƑŢŠ ţàƃļéš àŕé pg_trgm ĜÎÑ îñđéẋéš öñ plain, struct_key àñđ general_key àñđ à ĝéñéŕàţéđ search_tsv çöļüḿñ ŵîţĥ à ĜÎÑ îñđéẋ. Ţĥé ƒŕàḿéŵöŕķ šĥîþš öñļý ţĥé ŠǪĻîţé ƃàçķéñđ; à ŵîđéŕ ƃàçķéñđ ƃüîļţ öñ ţĥé šéçöñđ đîàļéçţ ŕüñš ţĥé šàḿé ƒüžžý šçöŕîñĝ îñ Ĝö öṽéŕ ţĥé çàñđîđàţéš îţš îñđéẋéš ŕéţŕîéṽé.

Þéŕƒöŕḿàñçé

ĐàţàšéţƂéƒöŕé (ƒüļļ šçàñ)Àƒţéŕ (ţŕîĝŕàḿ + Ļéṽéñšĥţéîñ)
1Ķ éñţŕîéš~5ḿš~2ḿš
10Ķ éñţŕîéš~50ḿš~5ḿš
100Ķ éñţŕîéš~500ḿš+~10-15ḿš

Šţöŕàĝé Ƃàçķéñđš

  1. Îñ-ḿéḿöŕý: ƒàšţ, éþĥéḿéŕàļ; ƒöŕ šéššîöñ-šçöþéđ ļéṽéŕàĝé đüŕîñĝ ƃàţçĥ þŕöçéššîñĝ.
  2. ŠǪĻîţé (ṽîà modernc.org/sqlite): þéŕšîšţéñţ; ḿàţçĥîñĝ ķéýš àŕé þŕé-çöḿþüţéđ àñđ îñđéẋéđ. ƑŢŠ5 ţŕîĝŕàḿ îñđéẋéš ƒöŕ ƒüžžý çàñđîđàţé ŕéţŕîéṽàļ; ƑŢŠ5 ŵöŕđ ţöķéñîžéŕ ƒöŕ ŕàñķéđ ÜÎ šéàŕçĥ. Þüŕé Ĝö ŵîţĥ ñö ÇĜö đéþéñđéñçîéš îñ ţĥé đéƒàüļţ ƃüîļđ.

Ĝéñéŕàļîžéđ àñđ šţŕüçţüŕàļ éẋàçţ ḿàţçĥîñĝ îš àñ îñđéẋéđ ļööķüþ, ƒàšţ éṽéñ ƒöŕ ļàŕĝé ḿéḿöŕîéš. Ƒüžžý ḿàţçĥîñĝ üšéš ţŕîĝŕàḿ çàñđîđàţé ŕéţŕîéṽàļ ţö ñàŕŕöŵ ţĥé šéàŕçĥ šþàçé, ţĥéñ Ļéṽéñšĥţéîñ šçöŕîñĝ öñ ~200 çàñđîđàţéš.

ŢḾẊ éļéḿéñţ ḿàþþîñĝ

Ţĥé îḿþöŕţ/éẋþöŕţ ļàýéŕ ḿàþš ƃéţŵééñ îñļîñé-çöđé ŕüñš àñđ ŢḾẊ îñļîñé éļéḿéñţš:

ŔüñŢḾẊ Éļéḿéñţ
Ph<ph>
PcOpen<bpt>
PcClose<ept>

Éñţîţý ḿéţàđàţà îš çàŕŕîéđ àš <prop> éļéḿéñţš öñ ţĥé ŢḾẊ <tu>. À ŢḾẊ ƒîļé çàŕŕýîñĝ öñļý þļàîñ ţéẋţ (ñö îñļîñé çöđéš) îḿþöŕţš àš Text-öñļý ŕüñ šéǫüéñçéš ŵîţĥ ñö éñţîţý ḿàþþîñĝš; ţĥöšé éñţŕîéš þàŕţîçîþàţé îñ þļàîñ ḿàţçĥîñĝ öñļý.