过滤与筛选 #
过滤概述 #
Algolia提供多种过滤方式来精确控制搜索结果:
| 过滤方式 | 用途 | 特点 |
|---|---|---|
| filters | 通用过滤 | 灵活的布尔表达式 |
| facetFilters | 分面过滤 | 简单易用,支持OR |
| numericFilters | 数值过滤 | 数值比较 |
| tagFilters | 标签过滤 | 简单标签匹配 |
filters参数 #
基本语法 #
javascript
// 等于
filters: 'brand:Apple'
// 不等于
filters: 'brand != Apple'
// 比较运算
filters: 'price < 1000'
filters: 'price <= 1000'
filters: 'price > 500'
filters: 'price >= 500'
布尔运算 #
javascript
// AND
filters: 'brand:Apple AND price < 1000'
// OR
filters: 'brand:Apple OR brand:Samsung'
// NOT
filters: 'NOT brand:Apple'
// 组合
filters: '(brand:Apple OR brand:Samsung) AND price < 1000'
字符串过滤 #
javascript
// 精确匹配
filters: 'name:"iPhone 15 Pro"'
// 前缀匹配(需要特殊处理)
filters: 'name:iPhone'
// 包含空格的值需要引号
filters: 'category:"Smart Phones"'
布尔过滤 #
javascript
// 布尔值
filters: 'inStock:true'
filters: 'featured:false'
数组过滤 #
javascript
// 数组字段匹配任意元素
filters: 'tags:phone'
// 多个标签
filters: 'tags:phone AND tags:5g'
嵌套属性过滤 #
javascript
// 使用点号访问嵌套属性
filters: 'specs.ram:8GB'
filters: 'author.name:John'
facetFilters参数 #
单个过滤 #
javascript
// 单个分面值
facetFilters: ['brand:Apple']
AND关系 #
javascript
// 多个条件(AND关系)
facetFilters: [
'brand:Apple',
'category:Phones',
'inStock:true'
]
OR关系 #
javascript
// 同一分面多选(OR关系)
facetFilters: [
['brand:Apple', 'brand:Samsung', 'brand:Google']
]
组合使用 #
javascript
// 复杂组合
facetFilters: [
['brand:Apple', 'brand:Samsung'], // Apple或Samsung
'category:Phones', // 且是手机
['color:Black', 'color:White'], // 且是黑色或白色
'inStock:true' // 且有库存
]
numericFilters参数 #
基本用法 #
javascript
// 单个条件
numericFilters: ['price < 1000']
// 多个条件
numericFilters: [
'price >= 500',
'price <= 1000',
'rating > 4'
]
比较运算符 #
| 运算符 | 说明 |
|---|---|
| = | 等于 |
| != | 不等于 |
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
组合条件 #
javascript
numericFilters: [
'price >= 500',
'price <= 1000',
'stock > 0',
'rating >= 4'
]
tagFilters参数 #
基本用法 #
javascript
// 单个标签
tagFilters: ['phone']
// 多个标签(AND关系)
tagFilters: ['phone', '5g']
// OR关系
tagFilters: [['phone', 'tablet']]
与数据字段配合 #
javascript
// 记录结构
{
"_tags": ["phone", "5g", "apple"]
}
// 或使用tags字段
{
"tags": ["phone", "5g", "apple"]
}
过滤器对比 #
filters vs facetFilters #
javascript
// filters - 更灵活
filters: 'brand:Apple AND (price < 1000 OR rating > 4)'
// facetFilters - 更简单
facetFilters: ['brand:Apple'] // 只能做简单的AND/OR
选择建议 #
| 场景 | 推荐 |
|---|---|
| 简单分面筛选 | facetFilters |
| 复杂布尔逻辑 | filters |
| 数值范围 | filters 或 numericFilters |
| 标签匹配 | tagFilters |
高级过滤 #
可选过滤器 #
javascript
// optionalFilters - 不影响搜索结果,只影响排名
index.search('phone', {
optionalFilters: ['brand:Apple<score=2>'],
filters: 'inStock:true'
});
// Apple品牌的结果排名更高,但不排除其他品牌
过滤器评分 #
javascript
// 为过滤器设置评分权重
index.search('phone', {
optionalFilters: [
'brand:Apple<score=5>',
'brand:Samsung<score=3>'
]
});
动态过滤 #
javascript
function buildFilters(conditions) {
const parts = [];
if (conditions.brand) {
parts.push(`brand:${conditions.brand}`);
}
if (conditions.minPrice || conditions.maxPrice) {
const priceFilters = [];
if (conditions.minPrice) {
priceFilters.push(`price >= ${conditions.minPrice}`);
}
if (conditions.maxPrice) {
priceFilters.push(`price <= ${conditions.maxPrice}`);
}
parts.push(`(${priceFilters.join(' AND ')})`);
}
if (conditions.inStock) {
parts.push('inStock:true');
}
return parts.join(' AND ');
}
// 使用
const filters = buildFilters({
brand: 'Apple',
minPrice: 500,
maxPrice: 1000,
inStock: true
});
// 结果: "brand:Apple AND (price >= 500 AND price <= 1000) AND inStock:true"
过滤器安全 #
用户输入转义 #
javascript
function escapeFilterValue(value) {
// 转义特殊字符
return value.replace(/([\\'"(){}[\]:])/g, '\\$1');
}
// 使用
const userInput = "O'Reilly";
const safeValue = escapeFilterValue(userInput);
filters: `brand:"${safeValue}"`
使用参数化查询 #
javascript
// 使用数组形式避免注入
const brand = "O'Reilly";
const filters = `brand:${JSON.stringify(brand)}`;
过滤器性能 #
过滤器优化 #
javascript
// ✅ 推荐:使用facetFilters
facetFilters: ['brand:Apple', 'category:Phones']
// ⚠️ 可行但较慢:使用filters
filters: 'brand:Apple AND category:Phones'
避免复杂嵌套 #
javascript
// ❌ 避免:过度嵌套
filters: '((brand:Apple OR brand:Samsung) AND (price < 1000 OR rating > 4)) OR (brand:Google AND price < 800)'
// ✅ 推荐:简化条件
filters: 'brand:Apple AND price < 1000'
过滤器示例 #
电商过滤 #
javascript
async function filterProducts(options) {
const {
query = '',
brands = [],
categories = [],
minPrice,
maxPrice,
inStock,
minRating,
colors = [],
sizes = []
} = options;
const filterParts = [];
// 品牌过滤
if (brands.length > 0) {
filterParts.push(`(${brands.map(b => `brand:${b}`).join(' OR ')})`);
}
// 分类过滤
if (categories.length > 0) {
filterParts.push(`(${categories.map(c => `category:${c}`).join(' OR ')})`);
}
// 价格范围
if (minPrice !== undefined || maxPrice !== undefined) {
const priceParts = [];
if (minPrice !== undefined) priceParts.push(`price >= ${minPrice}`);
if (maxPrice !== undefined) priceParts.push(`price <= ${maxPrice}`);
filterParts.push(`(${priceParts.join(' AND ')})`);
}
// 库存过滤
if (inStock !== undefined) {
filterParts.push(`inStock:${inStock}`);
}
// 评分过滤
if (minRating !== undefined) {
filterParts.push(`rating >= ${minRating}`);
}
// 颜色过滤
if (colors.length > 0) {
filterParts.push(`(${colors.map(c => `color:${c}`).join(' OR ')})`);
}
// 尺寸过滤
if (sizes.length > 0) {
filterParts.push(`(${sizes.map(s => `size:${s}`).join(' OR ')})`);
}
return await index.search(query, {
filters: filterParts.join(' AND '),
facets: ['brand', 'category', 'color', 'size']
});
}
内容过滤 #
javascript
async function filterContent(options) {
const {
query = '',
types = [],
authors = [],
tags = [],
dateFrom,
dateTo,
status = 'published'
} = options;
const filterParts = [];
// 状态过滤
filterParts.push(`status:${status}`);
// 类型过滤
if (types.length > 0) {
filterParts.push(`(${types.map(t => `type:${t}`).join(' OR ')})`);
}
// 作者过滤
if (authors.length > 0) {
filterParts.push(`(${authors.map(a => `author.id:${a}`).join(' OR ')})`);
}
// 标签过滤
if (tags.length > 0) {
filterParts.push(`(${tags.map(t => `tags:${t}`).join(' OR ')})`);
}
// 日期范围
if (dateFrom || dateTo) {
const dateParts = [];
if (dateFrom) dateParts.push(`publishedAt >= ${dateFrom}`);
if (dateTo) dateParts.push(`publishedAt <= ${dateTo}`);
filterParts.push(`(${dateParts.join(' AND ')})`);
}
return await index.search(query, {
filters: filterParts.join(' AND '),
facets: ['type', 'author.name', 'tags']
});
}
地理位置过滤 #
javascript
async function geoSearch(options) {
const {
query = '',
lat,
lng,
radius = 10000, // 10公里
country,
city
} = options;
const searchParams = {
facets: ['country', 'city']
};
// 地理位置过滤
if (lat && lng) {
searchParams.aroundLatLng = `${lat},${lng}`;
searchParams.aroundRadius = radius;
}
// 国家/城市过滤
const filterParts = [];
if (country) filterParts.push(`country:${country}`);
if (city) filterParts.push(`city:${city}`);
if (filterParts.length > 0) {
searchParams.filters = filterParts.join(' AND ');
}
return await index.search(query, searchParams);
}
过滤器工具函数 #
过滤器构建器 #
javascript
class FilterBuilder {
constructor() {
this.filters = [];
}
equals(field, value) {
this.filters.push(`${field}:${JSON.stringify(value)}`);
return this;
}
notEquals(field, value) {
this.filters.push(`${field} != ${JSON.stringify(value)}`);
return this;
}
in(field, values) {
const conditions = values.map(v => `${field}:${JSON.stringify(v)}`);
this.filters.push(`(${conditions.join(' OR ')})`);
return this;
}
range(field, min, max) {
const conditions = [];
if (min !== undefined) conditions.push(`${field} >= ${min}`);
if (max !== undefined) conditions.push(`${field} <= ${max}`);
this.filters.push(`(${conditions.join(' AND ')})`);
return this;
}
greaterThan(field, value) {
this.filters.push(`${field} > ${value}`);
return this;
}
lessThan(field, value) {
this.filters.push(`${field} < ${value}`);
return this;
}
boolean(field, value) {
this.filters.push(`${field}:${value}`);
return this;
}
build() {
return this.filters.join(' AND ');
}
}
// 使用
const builder = new FilterBuilder();
const filters = builder
.in('brand', ['Apple', 'Samsung'])
.range('price', 500, 1000)
.boolean('inStock', true)
.greaterThan('rating', 4)
.build();
// 结果: "(brand:Apple OR brand:Samsung) AND (price >= 500 AND price <= 1000) AND inStock:true AND rating > 4"
总结 #
过滤与筛选要点:
| 要点 | 说明 |
|---|---|
| filters | 通用布尔表达式过滤 |
| facetFilters | 简单分面过滤 |
| numericFilters | 数值过滤 |
| tagFilters | 标签过滤 |
| optionalFilters | 可选过滤(影响排名) |
| 安全性 | 转义用户输入 |
| 性能 | 优先使用facetFilters |
接下来,让我们学习 分页与排序。
最后更新:2026-03-28