Filtered approximate nearest-neighbor search

필터 결합 근사 최근접 검색

Apply metadata conditions while searching for nearby vectors.

···
html
<div class="v"><header><b>FILTERED ANN</b><span id="state"></span></header><main><div class="plane" id="plane"></div><div class="legend" id="legend"></div></main><footer>index candidates respect filter</footer></div>
css
.v{width:min(92vw,660px);height:min(86vh,310px);box-sizing:border-box;padding:clamp(9px,2.5vmin,18px);border:1px solid var(--line);border-radius:14px;background:var(--surface);display:flex;flex-direction:column;gap:7px;color:var(--fg);font:500 clamp(15px,4.5vmin,19px)/1.25 var(--font-sans, sans-serif)}.v header,.v footer{display:flex;justify-content:space-between;align-items:center;gap:8px;white-space:nowrap}.v header b{color:var(--accent);font-size:.9em}.v header span,.v footer{color:var(--muted);font-size:.82em}.v main{flex:1;min-height:0;position:relative;overflow:hidden}.v .mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.v .active{background:var(--accent)!important;color:var(--bg)!important;border-color:var(--accent)!important}.v .muted{opacity:.45} .plane{height:75%;position:relative;border:1px solid var(--line);border-radius:7px}.dot{position:absolute;width:13px;height:13px;border-radius:50%;background:var(--accent);transform:translate(-50%,-50%);transition:opacity .3s,transform .3s}.dot.blue{background:var(--accent-3)}.dot.hit{outline:2px solid var(--fg);outline-offset:3px;transform:translate(-50%,-50%) scale(1.2)}.query{position:absolute;left:48%;top:51%;font:700 1em ui-monospace,monospace}.legend{text-align:center;color:var(--muted);font-size:.8em}
js
const pts=[[20,25,0],[38,35,1],[60,32,0],[75,25,1],[24,70,1],[42,65,0],[65,68,1],[80,75,0]];let filtered=false;function draw(){document.getElementById("plane").innerHTML=pts.map((p,i)=>"<i class=\"dot "+(p[2]?"blue ":"")+(filtered&&!p[2]?"muted ":"")+(i===(filtered?6:5)?"hit":"")+"\" style=\"left:"+p[0]+"%;top:"+p[1]+"%\"></i>").join("")+"<b class=query>Q</b>";document.getElementById("legend").textContent=filtered?"blue only → nearest eligible":"all points → nearest overall";document.getElementById("state").textContent=filtered?"filter ON":"filter OFF";filtered=!filtered}draw();setInterval(draw,1350)

Approximate nearest-neighbor search follows index candidates instead of comparing every vector. Filtered search incorporates conditions such as category or tenant into candidate selection.

Filtering only after a small top-k search can discard every hit. The demo simplifies how a condition changes the eligible candidate set and returned neighbors.

When to use

Use it when vector results must satisfy permissions, category, or date constraints.

Open as page ↗