From 5ecd81c00217ddea0087d336d0dd1ce2b04b330e Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sun, 1 Nov 2026 19:04:58 -0800 Subject: [PATCH] S3 Vectors: array filters, and building weed-vector without protoc Filters now match array elements with $eq, a bare value and $in, with $ne/$nin as their opposites (seaweedfs#12321), checked live on master 54777d7fb9. weed-vector builds with no system protoc from inside seaweed-vector/ (seaweedfs#12317), checked in a clean rust:1.94.1-bookworm container. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK --- S3-Vector-Bucket.md | 11 +++++------ S3-Vectors-API.md | 12 +++++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/S3-Vector-Bucket.md b/S3-Vector-Bucket.md index ef1728f..2373597 100644 --- a/S3-Vector-Bucket.md +++ b/S3-Vector-Bucket.md @@ -27,17 +27,16 @@ SeaweedFS serves the [Amazon S3 Vectors](https://docs.aws.amazon.com/AmazonS3/la ## Getting weed-vector -`weed-vector` is not part of the release archives or the Docker images. Build it from source with Rust 1.94.1 or newer and `protoc`, which Lance's build scripts need: +No release or published Docker image includes `weed-vector` yet. Build it from source with Rust 1.94.1 or newer, running cargo inside `seaweed-vector/`. The workspace points Lance's build scripts at a bundled `protoc`, so no system `protoc` is needed: ```bash -sudo apt-get install -y protobuf-compiler # Debian/Ubuntu; provides protoc git clone https://github.com/seaweedfs/seaweedfs.git -cd seaweedfs -cargo build --release --locked --manifest-path seaweed-vector/Cargo.toml -p weed-vector-server -# the binary is seaweed-vector/target/release/weed-vector +cd seaweedfs/seaweed-vector +cargo build --release --locked -p weed-vector-server +# the binary is target/release/weed-vector ``` -Without `protoc` the build stops in `lance-encoding` with `Could not find protoc`. +Building from another directory with `--manifest-path` skips that setting. The build then needs `protoc` on `PATH` (or `PROTOC` set), or it stops in `lance-encoding` with `Could not find protoc`. ## Quick start diff --git a/S3-Vectors-API.md b/S3-Vectors-API.md index 50045ba..720d99e 100644 --- a/S3-Vectors-API.md +++ b/S3-Vectors-API.md @@ -93,18 +93,20 @@ s3v.query_vectors( | Filter | Matches | |--------|---------| -| `{"genre": "scifi"}` | `genre` equals `"scifi"` | -| `{"genre": {"$eq": "scifi"}}`, `{"$ne": ...}` | equal / not equal | +| `{"genre": "scifi"}` | `genre` equals `"scifi"`, or is an array that holds `"scifi"` | +| `{"genre": {"$eq": "scifi"}}`, `{"$ne": ...}` | equal / not equal; for an array, holds / does not hold the value | | `{"year": {"$gt": 1977}}`, `$gte`, `$lt`, `$lte` | numeric comparison; the operand must be a number (`$gt expects a number`) | -| `{"genre": {"$in": ["drama", "western"]}}`, `$nin` | equal to one of / none of the values | +| `{"genre": {"$in": ["drama", "western"]}}`, `$nin` | equal to (for an array, holds) one of / none of the values | | `{"tags": {"$exists": true}}` | the key is present (or absent, with `false`) | | `{"$and": [ ... ]}`, `{"$or": [ ... ]}` | all / any of the sub-filters | | `{"genre": "scifi", "year": 2014}` | several keys in one object: all must match | Behaviour to know: -* **Types are compared strictly.** `1`, `"1"`, `true` and `"true"` are four different values, for `$eq` as well as `$in` and `$nin`. -* **Only top-level scalar values match.** A filter does not look inside arrays: with `"tags": ["space", "classic"]`, neither `{"tags": "space"}` nor `{"tags": {"$in": ["space"]}}` matches; only `$exists` sees the key. A dotted path such as `{"info.lang": "fr"}` does not reach into a nested object either. +* **Arrays match by their elements.** With `"tags": ["space", "classic"]`, `{"tags": "space"}`, `{"tags": {"$eq": "classic"}}` and `{"tags": {"$in": ["prison", "space"]}}` all match. `$ne` and `$nin` are their opposites, so `{"tags": {"$ne": "space"}}` does not match. `$gt`, `$gte`, `$lt` and `$lte` do not look inside arrays: `{"scores": {"$gt": 2}}` does not match `"scores": [1, 2.5]`. +* **Types are compared strictly**, inside arrays too. `1`, `"1"`, `true` and `"true"` are four different values: `{"scores": 1}` matches `[1, 2.5]` but not `["1", "2.5"]`, and `{"flags": true}` matches `[true]` but not `["true"]`. +* **Nested objects are not searched.** A dotted path such as `{"info.lang": "fr"}` matches nothing, and `{"info": {"lang": "fr"}}` is rejected with `unsupported operator lang`. +* Array matching needs a gateway and a `weed-vector` of the same release. With an older `weed-vector`, a number or boolean can also match a string element with the same text. * An unknown operator is rejected (`unsupported operator $regex`), and so is a filter on a non-filterable key. ## Errors