Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Query and export data from seekdb vector database. Supports two search modes: (1) Scalar search - metadata filtering only, (2) Hybrid search - fulltext + semantic search combined. The --query-text parameter is used for BOTH fulltext ($contains) and semantic (query_texts) search simultaneously. Can export results to CSV/Excel.
.claude/skills/oceanbase-querying-from-seekdb/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 254% | 0% |
| case-13 | ✓→✗ | ▼ Worse | 383% | 0% |
| case-14 | ✓→✗ | ▼ Worse | 420% | 0% |
| case-10 | ✓→✗ | ▼ Worse | 331% | 0% |
| case-11 | ✓→✗ | ▼ Worse | 185% | 0% |
Query data from seekdb vector database with support for scalar search, hybrid search (fulltext + semantic), and export to CSV/Excel files.
> Note: All paths in this document (e.g., scripts/) are relative to THIS skill directory, not the project root.
bashpip install pyseekdb pandas openpyxl
MUST FOLLOW this workflow when handling user search requests:
Before constructing any query, you MUST understand the data structure. However, you should cache this information within the conversation.
Caching Rules:
--info to get metadata structure--info--info for the new collection--infobash# Get collection info to see metadata fields (only if not already known) python scripts/query_from_seekdb.py <collection_name> --info
This shows:
source, year, category)Example conversation flow:
User: "找 seekdb_demo 中 2023 年的教程"
→ Claude Code: 执行 --info (第一次查询此 collection)
→ 发现 metadata 有 source, year 字段
→ 执行搜索
User: "再找一下 notion 来源的"
→ Claude Code: 不需要再执行 --info (同一 collection,结构已知)
→ 直接执行搜索
User: "查一下 another_collection 中的数据"
→ Claude Code: 执行 --info (不同 collection)
→ 了解新 collection 的结构
→ 执行搜索Parse the user's natural language request to identify:
| Component | Look For | Maps To | |-----------|----------|---------| | Metadata conditions | Field-value pairs like "2023年", "来自notion", "价格<100" | --where filter | | Content/Semantic search | Keywords, concepts, descriptions, questions | --query-text (used for BOTH fulltext and semantic) |
Important: --query-text is used for BOTH fulltext search ($contains) and semantic search (query_texts) simultaneously. The same text is used for both.
User Request Analysis
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Does the request involve ONLY metadata field conditions? │
│ (e.g., "year=2023", "source=notion", no content search) │
└─────────────────────────────────────────────────────────────┘
│
├── YES ──► Scalar Search: --where only
│
└── NO ───► Does it involve content/semantic search?
│
├── YES (no metadata) ──► Hybrid Search: --query-text only
│
└── YES (with metadata) ──► Scalar + Hybrid: --where + --query-textWhen to use: User wants to filter by metadata fields ONLY, no content/semantic search needed.
bash# Filter by metadata fields only python scripts/query_from_seekdb.py seekdb_demo --where '{"source": "notion", "year": 2023}'
Example requests:
When to use: User wants to search by content - the query text is used for BOTH fulltext matching AND semantic similarity.
bash# Hybrid search: query text used for both fulltext ($contains) and semantic (query_texts) python scripts/query_from_seekdb.py seekdb_demo --query-text "seekdb 教程"
How it works:
--query-text "seekdb 教程" → Fulltext: where_document: {"$contains": "seekdb 教程"} + Semantic: query_texts: "seekdb 教程"Example requests:
--query-text "seekdb 教程"--query-text "python 技术文档"When to use: User wants metadata filtering + content/semantic search.
bash# Metadata filter + Hybrid search python scripts/query_from_seekdb.py seekdb_demo --query-text "seekdb 教程" --where '{"year": 2023}'
Example requests:
--query-text "seekdb 教程" --where '{"year": 2023}'--query-text "编程指南" --where '{"source": "notion"}'User request: "请找出 seekdb_demo 集合中 2023 年写的 seekdb 教程"
Step 1: Run --info to get metadata structure:
bashpython scripts/query_from_seekdb.py seekdb_demo --info # Output shows metadata fields: source, year
Step 2: Analyze request: | Part | Type | Filter | |------|------|--------| | "2023 年" | Metadata field year | --where '{"year": 2023}' | | "seekdb 教程" | Content/Semantic search | --query-text "seekdb 教程" |
Step 3: Execute:
bashpython scripts/query_from_seekdb.py seekdb_demo --query-text "seekdb 教程" --where '{"year": 2023}'
bash# List all collections python scripts/query_from_seekdb.py --list-collections # Show collection info (run this first to understand data structure!) python scripts/query_from_seekdb.py <collection_name> --info # Scalar search (metadata filter only) python scripts/query_from_seekdb.py <collection_name> --where '<json_filter>' # Hybrid search (fulltext + semantic, using same query text for both) python scripts/query_from_seekdb.py <collection_name> --query-text "<text>" [-n <count>] # Scalar + Hybrid search (metadata filter + fulltext + semantic) python scripts/query_from_seekdb.py <collection_name> --query-text "<text>" --where '<json>' # Export to CSV/Excel python scripts/query_from_seekdb.py <collection_name> <search_options> --output results.csv python scripts/query_from_seekdb.py <collection_name> <search_options> --output results.xlsx
| Option | Short | Description | |--------|-------|-------------| | --query-text | -q | Text for hybrid search (fulltext + semantic) | | --where | -w | Metadata filter as JSON string | | --n-results | -n | Number of results (default: 5) | | --output | -o | Export to file (.csv or .xlsx) | | --json | -j | Output as JSON | | --info | | Show collection info | | --list-collections | -l | List all collections | | --include | | Fields to include: documents,metadatas,embeddings | | --sheet-name | -s | Sheet name for Excel export |
Step 1: Run --info to see available metadata fields:
bashpython scripts/query_from_seekdb.py seekdb_demo --info # Example output: # Collection: seekdb_demo # Total records: 2 # Preview (first 3 records): # ID: doc1... # Document: python tutorial... # Metadata keys: ['source', 'year'] ← These are the metadata field names!
Step 2: Use the metadata field names to construct --where:
bash# From the output above, we know the collection has 'source' and 'year' fields # So we can filter by these fields: --where '{"source": "notion"}' # source equals "notion" --where '{"year": 2023}' # year equals 2023 --where '{"source": "notion", "year": 2023}' # both conditions (implicit AND)
Step 3: Match user request to metadata fields: | User says | Metadata field | --where value | |-----------|----------------|---------------| | "2023 年的" | year | '{"year": 2023}' | | "来自 notion 的" | source | '{"source": "notion"}' | | "价格低于 100 的" | price | '{"price": {"$lt": 100}}' | | "品牌是三星或苹果的" | brand | '{"brand": {"$in": ["Samsung", "Apple"]}}' |
| Operator | Description | Example | |----------|-------------|---------| | $eq | Equal to | {"year": {"$eq": 2023}} or {"year": 2023} | | $ne | Not equal to | {"status": {"$ne": "deleted"}} | | $gt | Greater than | {"score": {"$gt": 90}} | | $gte | Greater than or equal | {"score": {"$gte": 90}} | | $lt | Less than | {"score": {"$lt": 50}} | | $lte | Less than or equal | {"score": {"$lte": 50}} | | $in | In list | {"tag": {"$in": ["ml", "ai"]}} | | $nin | Not in list | {"tag": {"$nin": ["old"]}} | | $and | Logical AND | {"$and": [{"year": 2023}, {"source": "notion"}]} | | $or | Logical OR | {"$or": [{"year": 2023}, {"year": 2024}]} |
bash# Multiple conditions with implicit AND (both must be true) --where '{"source": "notion", "year": 2023}' # Explicit AND --where '{"$and": [{"source": "notion"}, {"year": {"$gte": 2023}}]}' # OR condition --where '{"$or": [{"source": "notion"}, {"source": "google-docs"}]}' # Range condition (year between 2022 and 2024) --where '{"$and": [{"year": {"$gte": 2022}}, {"year": {"$lte": 2024}}]}' # Combined AND + OR --where '{"$and": [{"year": 2023}, {"$or": [{"source": "notion"}, {"source": "obsidian"}]}]}'
bash# Export scalar search results to CSV python scripts/query_from_seekdb.py mobiles --where '{"Brand": "SAMSUNG"}' --output samsung.csv # Export hybrid search results to Excel python scripts/query_from_seekdb.py mobiles --query-text "good camera" --output results.xlsx # Export with custom sheet name python scripts/query_from_seekdb.py mobiles --query-text "phone" --output phones.xlsx --sheet-name "Search Results"
| Format | Extension | Description | |--------|-----------|-------------| | CSV | .csv | Comma-separated values, UTF-8 encoded with BOM | | Excel | .xlsx | Excel workbook format |
seekdb stores data in two distinct locations:
| Storage | Description | Filter Method | Example | |---------|-------------|---------------|---------| | Metadata | Structured key-value fields | --where | {"source": "notion", "year": 2023} | | Document | Text content | --query-text (hybrid search) | Fulltext + Semantic search |
Set environment variables for server mode:
| Variable | Description | Default | |----------|-------------|---------| | SEEKDB_HOST | Server host (if set, uses server mode) | - | | SEEKDB_PORT | Server port | 2881 | | SEEKDB_DATABASE | Database name | test | | SEEKDB_USER | Username | root | | SEEKDB_PASSWORD | Password | - |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-13 | pass→fail | 4,236 | 5,117 | +21% | 1 | 1 | 0% | 781 | 3,773 | +383% | 0 | 0 | — |
case-14 | pass→fail | 3,902 | 4,898 | +26% | 1 | 1 | 0% | 722 | 3,752 | +420% | 0 | 0 | — |
case-15 | fail→fail | 5,192 | 5,197 | +0% | 1 | 1 | 0% | 1,260 | 3,821 | +203% | 0 | 0 | — |
case-01 | fail→fail | 7,919 | 4,541 | -43% | 1 | 1 | 0% | 1,778 | 3,749 | +111% | 0 | 0 | — |
case-02 | fail→fail | 7,222 | 4,565 | -37% | 1 | 1 | 0% | 1,468 | 3,773 | +157% | 0 | 0 | — |
case-03 | fail→fail | 11,463 | 4,616 | -60% | 1 | 1 | 0% | 1,859 | 3,747 | +102% | 0 | 0 | — |
case-16 | fail→fail | 9,504 | 4,374 | -54% | 1 | 1 | 0% | 880 | 3,698 | +320% | 0 | 0 | — |
case-04 | fail→pass | 7,793 | 8,452 | +8% | 1 | 1 | 0% | 1,484 | 5,255 | +254% | 0 | 0 | — |
case-05 | fail→fail | 5,173 | 4,712 | -9% | 1 | 1 | 0% | 1,046 | 3,712 | +255% | 0 | 0 | — |
case-06 | fail→fail | 6,192 | 4,331 | -30% | 1 | 1 | 0% | 1,209 | 3,677 | +204% | 0 | 0 | — |
case-07 | fail→fail | 7,565 | 5,491 | -27% | 1 | 1 | 0% | 1,470 | 3,812 | +159% | 0 | 0 | — |
case-22 | fail→fail | 6,490 | 4,063 | -37% | 1 | 1 | 0% | 1,165 | 4,166 | +258% | 0 | 0 | — |
case-08 | fail→fail | 5,826 | 4,727 | -19% | 1 | 1 | 0% | 1,124 | 3,743 | +233% | 0 | 0 | — |
case-09 | fail→fail | 5,522 | 4,407 | -20% | 1 | 1 | 0% | 1,077 | 3,775 | +251% | 0 | 0 | — |
case-10 | pass→fail | 3,993 | 4,352 | +9% | 1 | 1 | 0% | 868 | 3,741 | +331% | 0 | 0 | — |
case-11 | pass→fail | 6,020 | 4,811 | -20% | 1 | 1 | 0% | 1,307 | 3,726 | +185% | 0 | 0 | — |
case-12 | pass→fail | 4,188 | 4,387 | +5% | 1 | 1 | 0% | 808 | 3,736 | +362% | 0 | 0 | — |
case-17 | fail→fail | 6,368 | 4,773 | -25% | 1 | 1 | 0% | 1,089 | 3,731 | +243% | 0 | 0 | — |
case-18 | pass→pass | 6,164 | 3,454 | -44% | 1 | 1 | 0% | 1,516 | 4,351 | +187% | 0 | 0 | — |
case-19 | fail→fail | 5,581 | 4,700 | -16% | 1 | 1 | 0% | 1,058 | 3,738 | +253% | 0 | 0 | — |
case-20 | fail→fail | 14,067 | 8,658 | -38% | 1 | 1 | 0% | 2,700 | 4,833 | +79% | 0 | 0 | — |
case-21 | fail→fail | 10,606 | 5,386 | -49% | 1 | 1 | 0% | 2,434 | 4,729 | +94% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 5 counted toward the lift figure. The other 17 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of -18 percentage points is the difference between those two pass rates over the 5 comparable cases. 6 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.