1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! Options + rarity-weighting seam for the `related` doc-similarity query. The
//! scorer itself lives on [`DocIndex::related`](crate::doc_index::DocIndex::related)
//! because it reads the inverted taxonomy and link indices; this module owns the
//! `Related` options struct and the `idf` seam that shapes scoring.
use PathBuf;
/// The reserved namespace name for the link graph. As a `related` weight key it
/// scores by the **whole, undirected wikilink graph** — not just backlinks. Two
/// pages are linked-related if any of these hold (the relation is symmetric: if
/// it relates A to B, it relates B to A):
/// - a page this page **links to** (its outbound targets), or
/// - a page that **links to** this page (its backlinks), or
/// - a page that **links to the same target** this page does (a shared outbound
/// reference — *bibliographic coupling*).
///
/// So this is broader than the [`backlinks`](crate::backlinks) filter, which is
/// the incoming direction only. Because the graph lives in its own index (not
/// the taxonomy map), a site may still *declare* a taxonomy literally named
/// `links`; it simply can't be addressed through `related` weights, where the
/// name is reserved for the graph.
pub const LINKS: &str = "links";
/// Per-query options for `related`.
/// Corpus-relative inverse-document-frequency weight for a shared term that
/// `df` of the corpus's `n` docs carry. A term shared by few docs outweighs a
/// common one, and rarity is measured *relative to corpus size* — so the same
/// `df` counts for more as the vault grows (a tag on 3 of 4 notes is common; on
/// 3 of 4000 it is rare). The `1.0 +` smooths the universal-term case (`df == n`
/// → `ln 2`) so a term on every doc still breaks ties rather than vanishing.
/// In practice `2 <= df <= n` (a term only `post` carries is shared with no one,
/// so it never scores), keeping the argument `> 1` and the result positive.