Retrieve, delete and count
Three point-level operations that do not involve a vector search: fetch known points by id, remove points, and count them.
export AETHERFY_API_KEY="afy_live_your_key_here"Setting up an Aetherfy collection for these examples
Python setup
Install with pip install aetherfy-vectors.
from aetherfy_vectors import AetherfyVectorsClient
from aetherfy_vectors.models import VectorConfig, DistanceMetric, Point
client = AetherfyVectorsClient()
client.create_collection(
"inventory",
VectorConfig(size=4, distance=DistanceMetric.COSINE),
)
client.upsert("inventory", [
Point(id=1, vector=[0.10, 0.20, 0.30, 0.40],
payload={"sku": "MOU-1", "category": "electronics", "price": 24.99}),
Point(id=2, vector=[0.15, 0.18, 0.33, 0.41],
payload={"sku": "KEY-2", "category": "electronics", "price": 189.00}),
Point(id=3, vector=[0.12, 0.22, 0.29, 0.38],
payload={"sku": "HUB-3", "category": "electronics", "price": 39.50}),
Point(id=4, vector=[0.90, 0.10, 0.05, 0.02],
payload={"sku": "MUG-4", "category": "kitchen", "price": 12.50}),
])JavaScript setup
Install with npm install aetherfy-vectors (Node >= 20).
import { AetherfyVectorsClient, DistanceMetric } from 'aetherfy-vectors';
const client = new AetherfyVectorsClient();
await client.createCollection('inventory', { size: 4, distance: DistanceMetric.COSINE });
await client.upsert('inventory', [
{ id: 1, vector: [0.10, 0.20, 0.30, 0.40],
payload: { sku: 'MOU-1', category: 'electronics', price: 24.99 } },
{ id: 2, vector: [0.15, 0.18, 0.33, 0.41],
payload: { sku: 'KEY-2', category: 'electronics', price: 189.00 } },
{ id: 3, vector: [0.12, 0.22, 0.29, 0.38],
payload: { sku: 'HUB-3', category: 'electronics', price: 39.50 } },
{ id: 4, vector: [0.90, 0.10, 0.05, 0.02],
payload: { sku: 'MUG-4', category: 'kitchen', price: 12.50 } },
]);Retrieving Aetherfy points by id in Python
retrieve fetches known points directly. It is not a search: there is no query vector, no score, and no ranking. Order is not guaranteed to match the order of the ids you passed, and ids that do not exist are simply absent from the result rather than returned as null.
from aetherfy_vectors import AetherfyVectorsClient
client = AetherfyVectorsClient()
points = client.retrieve("inventory", [1, 3], with_payload=True)
for p in points:
print(p)
# {'id': 1, 'payload': {'sku': 'MOU-1', 'category': 'electronics', 'price': 24.99}}
# {'id': 3, 'payload': {'sku': 'HUB-3', 'category': 'electronics', 'price': 39.5}}
# Ask for the stored vectors as well.
points = client.retrieve("inventory", [1], with_payload=True, with_vectors=True)
print(points[0]["vector"])
# [0.1, 0.2, 0.3, 0.4]
# Missing ids are omitted, not reported.
print(len(client.retrieve("inventory", [1, 999]))) # 1
client.close()retrieve returns a List[Dict] in the Aetherfy Python SDK — plain dictionaries, not Point dataclasses, so index them with p["id"] rather than p.id.
Retrieving Aetherfy points by id in JavaScript
import { AetherfyVectorsClient } from 'aetherfy-vectors';
const client = new AetherfyVectorsClient();
async function main() {
const points = await client.retrieve('inventory', [1, 3], { withPayload: true });
for (const p of points) console.log(p);
// { id: 1, payload: { sku: 'MOU-1', category: 'electronics', price: 24.99 } }
// { id: 3, payload: { sku: 'HUB-3', category: 'electronics', price: 39.5 } }
const withVecs = await client.retrieve('inventory', [1], {
withPayload: true,
withVectors: true,
});
console.log(withVecs[0].vector);
// [ 0.1, 0.2, 0.3, 0.4 ]
console.log((await client.retrieve('inventory', [1, 999])).length); // 1
client.dispose();
}
main();The JS SDK types the result as Point[], so p.id, p.payload and p.vector are property accesses.
Retrieve options in Aetherfy
| Python keyword | JavaScript option | Default | Effect |
|---|---|---|---|
with_payload | withPayload | True / true | Include the stored payload |
with_vectors | withVectors | False / false | Include the stored vector |
Ids obey the usual Aetherfy rules: an unsigned integer up to 2**53 - 1, or a UUID string. A slug such as "MOU-1" is rejected client-side with ValidationError, which is why the SKU above lives in the payload and not in the id.
Deleting Aetherfy points by id in Python
delete takes a points selector. Passing a list means “these ids”.
from aetherfy_vectors import AetherfyVectorsClient
client = AetherfyVectorsClient()
ok = client.delete("inventory", [4])
print(ok) # True
print(client.count("inventory")) # 3
print(len(client.retrieve("inventory", [4]))) # 0
client.close()Deleting Aetherfy points by filter in Python
Passing a filter object to the same parameter means “every point matching this”. The filter uses the standard must / should / must_not vocabulary.
from aetherfy_vectors import AetherfyVectorsClient
client = AetherfyVectorsClient()
ok = client.delete("inventory", {
"must": [
{"key": "category", "match": {"value": "electronics"}},
{"key": "price", "range": {"gte": 100}},
]
})
print(ok) # True
print(client.count("inventory")) # 2
client.close()There is no dry-run mode. Count first with the identical filter if you want to know what a delete will remove:
doomed = client.count("inventory", count_filter={
"must": [{"key": "category", "match": {"value": "electronics"}}]
})
print(doomed) # 2Deleting Aetherfy points in JavaScript
The same single parameter accepts either form.
import { AetherfyVectorsClient } from 'aetherfy-vectors';
const client = new AetherfyVectorsClient();
async function main() {
// By id list.
console.log(await client.delete('inventory', [4])); // true
// By filter. In JavaScript the clause key is mustNot; the SDK sends must_not.
console.log(await client.delete('inventory', {
must: [
{ key: 'category', match: { value: 'electronics' } },
{ key: 'price', range: { gte: 100 } },
],
mustNot: [{ key: 'sku', match: { value: 'MOU-1' } }],
})); // true
console.log(await client.count('inventory', { exact: true })); // 2
client.dispose();
}
main();In JavaScript write mustNot; the SDK translates it to the wire key must_not. Writing must_not directly in JavaScript throws, because the SDK validates clause keys against must, mustNot and should. That strictness matters most on delete: an exclusion clause that failed silently here would destroy data rather than merely return an extra row. Full detail in Filtered search.
Deleting Aetherfy points: the selector contract
| Selector value | Meaning |
|---|---|
| A list/array of ids | Delete exactly those points |
A filter object (must / should / must_not) | Delete every point matching the filter |
delete returns a bool in Python and resolves to a boolean in JavaScript. Neither SDK returns the number of points removed — call count before and after if you need that figure.
Counting Aetherfy points, and the exact default that differs
count returns a plain integer. It accepts an optional filter and an exact flag.
The two SDKs ship different defaults for exact. This is the single most likely source of a “the numbers don’t match between our Python job and our Node service” bug.
| SDK | Signature | Default for exact |
|---|---|---|
| Python | count(collection_name, count_filter=None, exact=True) | True — exact count |
| JavaScript | count(collectionName, { countFilter?, exact? }) | false — approximate count |
An exact count scans to produce a precise number and costs more on a large collection. An approximate count is cheaper and may be off. Neither default is wrong, but they are not the same, so pass exact explicitly in both languages whenever the number is compared, asserted on, or shown to a user.
Counting in Aetherfy with Python
from aetherfy_vectors import AetherfyVectorsClient
client = AetherfyVectorsClient()
# Default is exact=True in Python.
print(client.count("inventory")) # 4
# Be explicit anyway.
print(client.count("inventory", exact=True)) # 4
# Cheaper approximate count.
print(client.count("inventory", exact=False)) # approximate integer
# Counting a subset.
print(client.count(
"inventory",
count_filter={"must": [{"key": "category", "match": {"value": "electronics"}}]},
exact=True,
)) # 3
client.close()Counting in Aetherfy with JavaScript
import { AetherfyVectorsClient } from 'aetherfy-vectors';
const client = new AetherfyVectorsClient();
async function main() {
// Default is exact: false in JavaScript — this may be approximate.
console.log(await client.count('inventory'));
// Match the Python default explicitly.
console.log(await client.count('inventory', { exact: true })); // 4
// Counting a subset.
console.log(await client.count('inventory', {
countFilter: { must: [{ key: 'category', match: { value: 'electronics' } }] },
exact: true,
})); // 3
client.dispose();
}
main();Aetherfy method reference for this page
| Operation | Python | JavaScript | Returns |
|---|---|---|---|
| Fetch by id | retrieve(collection_name, ids, with_payload=True, with_vectors=False) | retrieve(collectionName, ids, { withPayload?, withVectors? }) | List[Dict] / Promise<Point[]> |
| Delete | delete(collection_name, points_selector) | delete(collectionName, pointsSelector) | bool / Promise<boolean> |
| Count | count(collection_name, count_filter=None, exact=True) | count(collectionName, { countFilter?, exact? }) | int / Promise<number> |
Related: Filtered search for the filter object, Collection lifecycle & schema for removing a whole collection instead of its points.