> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pubrio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 筛选器概览

> Pubrio 搜索筛选器的工作原理 — 统一的筛选引擎、AND/OR 语义,以及何时使用哪种。

Pubrio 的搜索端点(`/companies/search`、`/people/search`、`/companies/advertisements/search`)共享同一个筛选引擎。你只需编写一次请求体,相同的规则就会在各个端点上生效 — 包括多值筛选器的组合方式、位置匹配方式,以及如何通过 `filter_conditions` 覆盖默认操作符。

## 为什么使用统一筛选引擎?

<CardGroup cols={2}>
  <Card title="一套结构,三个端点" icon="arrows-rotate">
    `technologies`、`verticals`、`founded_dates` 等公司级筛选器在 `/companies/search`、`/people/search` 以及 Monitor `company_filters` 中行为一致 — 你只需学一次。
  </Card>

  <Card title="按筛选项设置 AND/OR" icon="code-merge">
    默认是 OR(任一匹配)。在 `filter_conditions` 中添加一条记录就能将单个筛选器升级为 AND(全部匹配)— 无需改动其他字段。
  </Card>

  <Card title="原生 Postgres 操作符" icon="database">
    数组筛选器编译为原生 Postgres 操作符 — OR 对应 `&&`(重叠),AND 对应 `@>`(包含)。索引友好,无需应用层后置过滤。
  </Card>

  <Card title="Monitor 中通用" icon="bell">
    [Monitor](/cn/developer-guides/introduction) 中的 `company_filters` 块接受相同结构,因此一份能跑通的搜索请求体也能直接用于 monitor。
  </Card>
</CardGroup>

***

## 搜索请求的结构

每个搜索请求由同一个 JSON 请求体中的三层组成:

| 层级    | 位置                                                    | 示例                                                                         |
| ----- | ----------------------------------------------------- | -------------------------------------------------------------------------- |
| 人员筛选器 | 顶层字段                                                  | `people_titles`、`management_levels`、`departments`、`people_locations`       |
| 公司筛选器 | 嵌套在 `company_filters: {...}` 中(推荐)— 也可放在顶层            | `technologies`、`verticals`、`founded_dates`、`employees`、`company_locations` |
| 操作符覆盖 | `filter_conditions` 数组(覆盖公司键时放在 `company_filters` 内部) | `[{ "key": "technologies", "operator": "and" }]`                           |

一个最小化的 `/people/search` 请求,三层都用上:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.pubrio.com/people/search \
    -H "Content-Type: application/json" \
    -H "pubrio-api-key: YOUR_API_KEY" \
    -d '{
      "people_titles": ["VP of Engineering", "CTO"],
      "company_filters": {
        "technologies": ["Kubernetes", "Docker"],
        "is_enable_similarity_search": true,
        "company_locations": ["US"]
      },
      "per_page": 25,
      "page": 1
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.pubrio.com/people/search",
      headers={
          "Content-Type": "application/json",
          "pubrio-api-key": "YOUR_API_KEY",
      },
      json={
          "people_titles": ["VP of Engineering", "CTO"],
          "company_filters": {
              "technologies": ["Kubernetes", "Docker"],
              "is_enable_similarity_search": True,
              "company_locations": ["US"],
          },
          "per_page": 25,
          "page": 1,
      },
  )
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.pubrio.com/people/search", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "pubrio-api-key": "YOUR_API_KEY",
    },
    body: JSON.stringify({
      people_titles: ["VP of Engineering", "CTO"],
      company_filters: {
        technologies: ["Kubernetes", "Docker"],
        is_enable_similarity_search: true,
        company_locations: ["US"],
      },
      per_page: 25,
      page: 1,
    }),
  });
  console.log(await response.json());
  ```
</CodeGroup>

## `company_filters`:把公司级键归成一组

`company_filters: {...}` 包装对象是发送公司级筛选的推荐方式 — 它直观地分开了哪些键筛选*人员*、哪些键筛选*公司*,而且与 [Monitor](/cn/developer-guides/introduction) 已经在用的结构一致,搜索与 monitor 配置之间的载荷可以直接互相搬迁。

两种风格都支持;引擎在处理前会把包装形式摊平到顶层,**同名时顶层键优先**:

<CodeGroup>
  ```json 包装形式(推荐) theme={null}
  {
    "people_titles": ["VP of Engineering"],
    "company_filters": {
      "technologies": [37, 152],
      "founded_dates": [2015, 2023],
      "company_locations": ["US"]
    }
  }
  ```

  ```json 摊平形式(也可用) theme={null}
  {
    "people_titles": ["VP of Engineering"],
    "technologies": [37, 152],
    "founded_dates": [2015, 2023],
    "company_locations": ["US"]
  }
  ```
</CodeGroup>

为公司级键添加 `filter_conditions` 覆盖时,把它放在 `company_filters` **内部**,这样它和它覆盖的键一起。

### `/search/similar` 变体使用相同的请求体

`POST /companies/search/similar` 和 `POST /people/search/similar` 接受与其非相似版本**相同的筛选器请求体**(包括 `company_filters` 包装和 `filter_conditions`)。每个端点在此之上叠加相似度步骤:

|                             | 额外需要                                                                                       | 额外返回                                      |
| --------------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------- |
| `/companies/search/similar` | 参照公司 — `domain_search_id`、`domain`、`linkedin_url` 或 `domains`                              | 每条结果带 `similarity_score`(浮点 0-1),按相似度倒序排列 |
| `/people/search/similar`    | 参照人物/职位 — `people_titles`、`people_search_id`、`linkedin_url`、`linkedin_urls` 或 `peoples` 之一 | 同上 — 每条结果带 `similarity_score`,按相似度倒序排列    |

响应外层结构与标准 `search` 端点一致。筛选器在相似度排名之前先收敛候选集 — 因此把 `company_locations: ["US"]` 与 `/people/search/similar` 结合,会返回符合约束的、最接近你参照职位的美国人物,即"在这些条件下找到更多类似 X 的人"的模式。

<Note>
  与标准 `/search` 端点不同,`/search/similar` **不会**返回精确的 `pagination.total_entries` — 该值是被截断的,因为相似度搜索按相关性排序,只返回最佳匹配。请使用相似度搜索来寻找*最佳*匹配,而不是枚举所有结果。
</Note>

***

## AND vs OR — 每个筛选器只需做一个决定

多值筛选器(`technologies`、`verticals`、`keywords`、`categories`……)接受数组。操作符决定"匹配"的含义:

<Tabs>
  <Tab title="OR(默认)">
    **匹配任一值。** 返回数组与输入有重叠的行。

    ```json theme={null}
    {
      "technologies": ["Python", "PostgreSQL", "Kubernetes"],
      "is_enable_similarity_search": true
    }
    ```

    只要公司的技术栈包含 `Python`、`PostgreSQL` 或 `Kubernetes` 中**任何一个**,就会被纳入结果。编译为 Postgres `column && ARRAY[...]`。

    适用于:你想要覆盖广 — "对其中*任何一个*感兴趣"、"位于*任何一个*国家"。
  </Tab>

  <Tab title="AND">
    **匹配每个值。** 返回数组包含所有输入值的行。

    ```json theme={null}
    {
      "technologies": [37, 152, 408],
      "filter_conditions": [
        { "key": "technologies", "operator": "and" }
      ]
    }
    ```

    Numeric tag IDs come from `GET /technologies?search_term=python` (and similar). **Don't combine `is_enable_similarity_search: true` with AND on the same key** — similarity expands each free-text term into many tag IDs and `@>` then requires the row to contain all of them, which almost always returns zero.

    只有公司技术栈包含 `[37, 152, 408]` 中**所有项**时才会被纳入。编译为 Postgres `column @> ARRAY[...]`。

    适用于:你需要精度 — "*同时*使用这些技术"、"标签同时包含*所有*垂直行业"。
  </Tab>
</Tabs>

<Note>
  未列入 `filter_conditions` 的筛选器使用默认操作符(数组内为 OR,不同筛选键之间为 AND)。你只需声明覆盖,不需要写默认值。
</Note>

***

## 可覆盖的键

每个端点接受一组不同的键。键名来自每个 `*_filter_conditions` 模式中的 OpenAPI 枚举:

<CardGroup cols={3}>
  <Card title="公司端点" icon="building" href="/cn/api-reference/endpoint/companies/search">
    `company_filter_conditions` 键:`keywords`、`verticals`、`vertical_categories`、`vertical_sub_categories`、`technologies`、`categories`、`advertisement_target_locations`、`advertisement_exclude_target_locations`、`advertisement_search_terms`、`places`、`exclude_places`、`job_exclude_locations`。
  </Card>

  <Card title="人员端点" icon="user" href="/cn/api-reference/endpoint/people/search">
    `people_filter_conditions` 键(委托给公司引擎):`keywords`、`verticals`、`vertical_categories`、`vertical_sub_categories`、`technologies`、`categories`、`places`、`exclude_places`,以及 `social_media`。
  </Card>

  <Card title="广告端点" icon="bullhorn" href="/cn/api-reference/endpoint/companies/advertisements_search">
    `ads_filter_conditions` 键:`target_locations`、`exclude_target_locations`。范围较小,因为广告只按投放国家筛选。
  </Card>
</CardGroup>

<Tip>
  在 `/people/search` 中,公司级位置的 `filter_conditions[].key` 使用公司引擎的**裸名** — `places`、`exclude_places` — 不是带前缀的人员 API 名称(`company_places`)。详见 [人员 + 公司筛选器](/cn/developer-guides/filters/people-with-company-filters#key-remap-reference)。
</Tip>

***

## 性能建议

<AccordionGroup>
  <Accordion title="尽早在已建索引的列上筛选" icon="bolt">
    位置、员工区间和 `founded_dates` 都已建索引,缩小候选集的速度比文本或垂直筛选更快。先用一两个精确筛选,再考虑相似度搜索。
  </Accordion>

  <Accordion title="不要在大数组上滥用 AND" icon="triangle-exclamation">
    `column @> ARRAY[a, b, c, …]` 要求所有值都存在。基数增长很快 — 在平均只标 3 个技术标签的类目上对 10 个 tech 做 AND 几乎返回零行,且会触发全表扫描。AND 筛选保持 2-4 个值;探索性查询用 OR。
  </Accordion>

  <Accordion title="自由文本输入用 is_enable_similarity_search" icon="wand-magic-sparkles">
    如果你拿不到 slug ID(verticals、technologies、categories),只有自由文本字符串,可设置 `is_enable_similarity_search: true`、`similarity_score: 0.7`。引擎会先解析匹配再筛选 — 比扫描文本便宜得多。
  </Accordion>

  <Accordion title="规模和收入优先用区间而非枚举列表" icon="arrows-left-right">
    `employees: [[201, 500], [501, 1000]]`(区间数组)和 `revenues: [1000000, 5000000]`(单个最小/最大范围)比长 ID 列表更快、更地道。
  </Accordion>
</AccordionGroup>

***

## 后续步骤

<CardGroup cols={2}>
  <Card title="filter_conditions" icon="code-merge" href="/cn/developer-guides/filters/filter-conditions">
    参考页 — 每个支持的键、每个默认值,以及可复制的 AND/OR 配方。
  </Card>

  <Card title="人员 + 公司筛选器" icon="users-rectangle" href="/cn/developer-guides/filters/people-with-company-filters">
    在 `/people/search` 中使用任意公司筛选器。统一引擎的标志性新功能。
  </Card>

  <Card title="公司搜索参考" icon="building" href="/cn/api-reference/endpoint/companies/search">
    `/companies/search` 的完整请求/响应结构。
  </Card>

  <Card title="人员搜索参考" icon="user" href="/cn/api-reference/endpoint/people/search">
    `/people/search` 的完整请求/响应结构。
  </Card>
</CardGroup>

<Note>
  寻找仪表板侧的筛选教程?请参阅知识库中的 [筛选与导出联系人](/cn/knowledge-base/concepts/search-filters)。
</Note>
