> ## 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.

# Operadores AND / OR

> Anula el operador AND/OR por defecto para cualquier filtro multivalor — referencia completa con ejemplos copiables.

`filter_conditions` es un único array opcional en el cuerpo de la solicitud. Cada entrada promueve un filtro multivalor del comportamiento OR ("coincide con cualquiera") por defecto a AND ("coincide con todos"), o viceversa. Los filtros que no listes conservan su comportamiento por defecto.

## Esquema

<CodeGroup>
  ```json JSON theme={null}
  {
    "filter_conditions": [
      { "key": "technologies", "operator": "and" },
      { "key": "verticals",    "operator": "or"  }
    ]
  }
  ```

  ```typescript TypeScript theme={null}
  type FilterCondition = {
    /** Nombre del filtro a anular. Ver "Claves admitidas" a continuación. */
    key: string;
    /** No distingue mayúsculas/minúsculas: "and" | "or". El valor por defecto es "or" para arrays. */
    operator: "and" | "or";
  };

  type SearchRequest = {
    // …todos tus demás filtros…
    filter_conditions?: FilterCondition[];
  };
  ```
</CodeGroup>

<Note>
  `key` y `operator` son obligatorios en cada entrada. Una entrada con solo `operator` se ignora silenciosamente — no existe una anulación global.
</Note>

***

## Por qué importa

El operador por defecto es OR porque la mayoría de los flujos de prospección buscan un alcance amplio: "personas en *cualquiera* de estos países", "empresas etiquetadas con *cualquiera* de estos verticales". Para segmentación de alta precisión — "usa *todas* de `Salesforce` + `HubSpot` + `Marketo`" — necesitas AND.

El costo de equivocarse:

* **Querías AND, obtuviste OR:** la respuesta sobre-recupera — ves empresas que coinciden con solo una etiqueta, no con el conjunto completo. Fácil de detectar, cuesta calidad de resultado.
* **Querías OR, obtuviste AND:** la respuesta sub-recupera — normalmente devuelve casi cero filas en filtros multivalor con AND, porque los arrays del mundo real rara vez contienen todos los valores solicitados. Fácil de detectar, parece una consulta rota.

Internamente, el motor compila tu elección de operador a un operador nativo de array de Postgres: `&&` (solapamiento) para OR, `@>` (contiene) para AND. Ambos son compatibles con índices, así que la diferencia de costo está en el *tamaño del resultado*, no en la latencia de la consulta.

***

## Claves admitidas

El conjunto exacto de claves depende del endpoint que estés llamando:

| Clave                                    | `/companies/search` | `/people/search` | `/companies/advertisements/search` | Por defecto | Qué significa `and`                                           |
| ---------------------------------------- | ------------------- | ---------------- | ---------------------------------- | ----------- | ------------------------------------------------------------- |
| `technologies`                           | sí                  | sí               | —                                  | OR          | Tiene todas las tecnologías de la lista                       |
| `categories`                             | sí                  | sí               | —                                  | OR          | Etiquetado con todas las categorías                           |
| `verticals`                              | sí                  | sí               | —                                  | OR          | Pertenece a todos los verticales                              |
| `vertical_categories`                    | sí                  | sí               | —                                  | OR          | En todas las categorías de vertical                           |
| `vertical_sub_categories`                | sí                  | sí               | —                                  | OR          | En todas las subcategorías de vertical                        |
| `keywords`                               | sí                  | sí               | —                                  | OR          | La descripción contiene todas las palabras clave              |
| `places`                                 | sí                  | sí               | —                                  | OR          | Listado en todos los lugares                                  |
| `exclude_places`                         | sí                  | sí               | —                                  | OR          | Excluido de todos los lugares                                 |
| `advertisement_target_locations`         | sí                  | —                | —                                  | OR          | El anuncio apunta a todos los países (endpoint de empresas)   |
| `advertisement_exclude_target_locations` | sí                  | —                | —                                  | OR          | El anuncio excluye todos los países                           |
| `advertisement_search_terms`             | sí                  | —                | —                                  | OR          | El texto del anuncio contiene todos los términos              |
| `job_exclude_locations`                  | sí                  | —                | —                                  | OR          | La publicación de empleo excluye todas las ubicaciones        |
| `social_media`                           | —                   | sí               | —                                  | OR          | La persona tiene todas las cuentas de redes sociales listadas |
| `target_locations`                       | —                   | —                | sí                                 | OR          | El anuncio apunta a todos los países (endpoint de anuncios)   |
| `exclude_target_locations`               | —                   | —                | sí                                 | OR          | El anuncio excluye todos los países                           |

<Tip>
  Las claves anteriores reflejan los arrays `enum` en la especificación OpenAPI (`company_filter_conditions`, `people_filter_conditions`, `ads_filter_conditions`). Enviar una clave no admitida para un endpoint se ignora silenciosamente.
</Tip>

***

## Recetas

<Tabs>
  <Tab title="Todas las tecnologías (empresas)">
    **Objetivo:** empresas que usan *todas* Python, PostgreSQL y Kubernetes — no solo una.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.pubrio.com/companies/search \
        -H "Content-Type: application/json" \
        -H "pubrio-api-key: YOUR_API_KEY" \
        -d '{
          "technologies": [37, 152, 408],
          "filter_conditions": [
            { "key": "technologies", "operator": "and" }
          ],
          "per_page": 25,
          "page": 1
        }'
      ```

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

      response = requests.post(
          "https://api.pubrio.com/companies/search",
          headers={
              "Content-Type": "application/json",
              "pubrio-api-key": "YOUR_API_KEY",
          },
          json={
              "technologies": [37, 152, 408],
              "filter_conditions": [
                  { "key": "technologies", "operator": "and" }
              ],
              "per_page": 25,
              "page": 1,
          },
      )
      print(response.json())
      ```

      ```javascript Node.js theme={null}
      const response = await fetch("https://api.pubrio.com/companies/search", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "pubrio-api-key": "YOUR_API_KEY",
        },
        body: JSON.stringify({
          technologies: [37, 152, 408],
          filter_conditions: [
            { key: "technologies", operator: "and" }
          ],
          per_page: 25,
          page: 1,
        }),
      });
      console.log(await response.json());
      ```
    </CodeGroup>

    Quita la entrada `filter_conditions` para ampliar la búsqueda a *cualquiera* de las tres.
  </Tab>

  <Tab title="Cualquier ubicación + exclusión">
    **Objetivo:** empresas en *cualquiera* de EE. UU., Canadá o Reino Unido, pero nunca en San Francisco.

    OR ya es el valor por defecto para `locations`, así que lo dejamos implícito. `exclude_places` gestiona el filtro negativo de forma independiente — no se necesita anulación.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.pubrio.com/companies/search \
        -H "Content-Type: application/json" \
        -H "pubrio-api-key: YOUR_API_KEY" \
        -d '{
          "locations": ["US", "CA", "GB"],
          "exclude_places": ["San Francisco"],
          "per_page": 25,
          "page": 1
        }'
      ```

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

      response = requests.post(
          "https://api.pubrio.com/companies/search",
          headers={
              "Content-Type": "application/json",
              "pubrio-api-key": "YOUR_API_KEY",
          },
          json={
              "locations": ["US", "CA", "GB"],
              "exclude_places": ["San Francisco"],
              "per_page": 25,
              "page": 1,
          },
      )
      print(response.json())
      ```

      ```javascript Node.js theme={null}
      const response = await fetch("https://api.pubrio.com/companies/search", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "pubrio-api-key": "YOUR_API_KEY",
        },
        body: JSON.stringify({
          locations: ["US", "CA", "GB"],
          exclude_places: ["San Francisco"],
          per_page: 25,
          page: 1,
        }),
      });
      console.log(await response.json());
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Campañas publicitarias multirregión">
    **Objetivo:** anuncios que apuntan activamente *tanto* a la UE *como* a EE. UU. (campañas multirregión) — no anuncios de un solo mercado. Usa el esquema dedicado `ads_filter_conditions` con la clave `target_locations`.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.pubrio.com/companies/advertisements/search \
        -H "Content-Type: application/json" \
        -H "pubrio-api-key: YOUR_API_KEY" \
        -d '{
          "target_locations": ["US", "DE", "FR"],
          "filter_conditions": [
            { "key": "target_locations", "operator": "and" }
          ],
          "start_dates": ["2026-01-01"],
          "end_dates":   ["2026-04-22"],
          "per_page": 25,
          "page": 1
        }'
      ```

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

      response = requests.post(
          "https://api.pubrio.com/companies/advertisements/search",
          headers={
              "Content-Type": "application/json",
              "pubrio-api-key": "YOUR_API_KEY",
          },
          json={
              "target_locations": ["US", "DE", "FR"],
              "filter_conditions": [
                  { "key": "target_locations", "operator": "and" }
              ],
              "start_dates": ["2026-01-01"],
              "end_dates":   ["2026-04-22"],
              "per_page": 25,
              "page": 1,
          },
      )
      print(response.json())
      ```

      ```javascript Node.js theme={null}
      const response = await fetch("https://api.pubrio.com/companies/advertisements/search", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "pubrio-api-key": "YOUR_API_KEY",
        },
        body: JSON.stringify({
          target_locations: ["US", "DE", "FR"],
          filter_conditions: [
            { key: "target_locations", operator: "and" }
          ],
          start_dates: ["2026-01-01"],
          end_dates:   ["2026-04-22"],
          per_page: 25,
          page: 1,
        }),
      });
      console.log(await response.json());
      ```
    </CodeGroup>

    <Note>
      El endpoint de anuncios usa su propio esquema `ads_filter_conditions` (conjunto de claves más reducido: `target_locations`, `exclude_target_locations`). Las claves que puedes anular en `/companies/search` y `/people/search` *no* aplican aquí.
    </Note>
  </Tab>

  <Tab title="Personas en empresas con stack múltiple">
    **Objetivo:** personas que trabajan en empresas que tienen instalados *tanto* Salesforce *como* HubSpot — una señal clásica de desplazamiento de CRM. Demuestra el motor unificado: misma clave `technologies`, mismo operador, pero en `/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": ["RevOps", "Sales Operations"],
          "technologies": [114, 287],
          "filter_conditions": [
            { "key": "technologies", "operator": "and" }
          ],
          "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": ["RevOps", "Sales Operations"],
              "technologies": [114, 287],
              "filter_conditions": [
                  { "key": "technologies", "operator": "and" }
              ],
              "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: ["RevOps", "Sales Operations"],
          technologies: [114, 287],
          filter_conditions: [
            { key: "technologies", operator: "and" }
          ],
          per_page: 25,
          page: 1,
        }),
      });
      console.log(await response.json());
      ```
    </CodeGroup>
  </Tab>
</Tabs>

***

## Errores comunes

<AccordionGroup>
  <Accordion title="Olvidar key y enviar solo operator" icon="circle-xmark">
    No existe un interruptor global de "operador por defecto". Cada entrada debe nombrar un filtro específico:

    ```json theme={null}
    // Se ignora — sin key
    { "filter_conditions": [{ "operator": "and" }] }

    // Correcto — anula solo el filtro technologies
    { "filter_conditions": [{ "key": "technologies", "operator": "and" }] }
    ```
  </Accordion>

  <Accordion title="Esperar que las entradas se combinen" icon="circle-xmark">
    Las entradas son anulaciones independientes por clave — no se encadenan. Listar tanto `technologies` como `verticals` no crea una expresión booleana entre ellas; cada una simplemente establece el operador de su propio array.

    La combinación *entre* claves de filtro siempre es AND (todos los filtros deben coincidir). No puedes combinar con OR dos dimensiones de filtro distintas mediante `filter_conditions`. Si necesitas una búsqueda con un verdadero OR entre filtros diferentes, ejecuta dos solicitudes y combina los resultados en el cliente.
  </Accordion>

  <Accordion title="Usar AND en un array largo" icon="triangle-exclamation">
    AND es `column @> ARRAY[…]` — cada valor debe estar presente. Con 8 o más valores casi siempre obtienes cero filas porque el etiquetado en el mundo real es disperso. Mantén los arrays con AND anulado entre 2 y 4 valores; usa OR para filtrado exploratorio o a nivel de categoría.
  </Accordion>

  <Accordion title="Clave incorrecta en los filtros de empresa de /people/search" icon="circle-xmark">
    En `/people/search`, el nombre en la API de personas es `company_places` / `company_locations`. Pero dentro de `filter_conditions[].key` debes usar el **nombre del motor** — `places`, `locations`. El remapeo ocurre internamente antes de que se consulte `filter_conditions`.

    ```json theme={null}
    // No anula — el motor no reconoce "company_places" como clave de filtro
    { "filter_conditions": [{ "key": "company_places", "operator": "and" }] }

    // Correcto
    { "filter_conditions": [{ "key": "places", "operator": "and" }] }
    ```

    Tabla de remapeo completa en la página [Personas + Filtros de empresa](/es/developer-guides/filters/people-with-company-filters#key-remap-reference).
  </Accordion>
</AccordionGroup>

<Tip>
  Ante la duda, omite `filter_conditions` primero y verifica el conteo de resultados frente a tus expectativas. Añade anulaciones solo para los filtros donde el comportamiento por defecto no coincide con tu intención — esto mantiene el payload de la solicitud más pequeño y fácil de depurar.
</Tip>

***

## Ver también

<CardGroup cols={2}>
  <Card title="Resumen de filtros" icon="filter" href="/es/developer-guides/filters/overview">
    El modelo mental — empieza aquí si `filter_conditions` es tu primera parada.
  </Card>

  <Card title="Personas + Filtros de empresa" icon="users-rectangle" href="/es/developer-guides/filters/people-with-company-filters">
    Cómo incorporar filtros de empresa en `/people/search`, incluyendo el remapeo de claves.
  </Card>

  <Card title="Referencia de Company Search" icon="building" href="/es/api-reference/endpoint/companies/search">
    Esquema completo de la solicitud para `/companies/search` (incluye `company_filter_conditions`).
  </Card>

  <Card title="Referencia de People Search" icon="user" href="/es/api-reference/endpoint/people/search">
    Esquema completo de la solicitud para `/people/search` (incluye `people_filter_conditions`).
  </Card>
</CardGroup>
