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

# Advanced Search

> Perform multi-criteria search across OMOP medical vocabularies with advanced filtering by domain, vocabulary, concept class, and standard status.

## Overview

The advanced search endpoint provides powerful multi-criteria search capabilities across healthcare vocabularies. Use complex queries, filters, and ranking to find the most relevant medical concepts.

<Info>
  **Best for:** Complex search scenarios requiring multiple filters, specific vocabularies, or advanced ranking criteria.
</Info>

<Warning>
  **Query Requirements:** Queries must be at least 3 characters long OR include at least one filter (`vocabulary_ids`, `domain_ids`, or `concept_class_ids`). This prevents overly broad searches that could timeout.
</Warning>

## Endpoint

<ParamField path="POST" type="string">
  /v1/search/advanced
</ParamField>

## Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token with your API key
</ParamField>

## Request Body

<ParamField body="query" type="string" required>
  The search query term

  **Example:** `"diabetes mellitus type 2"`

  **Validation:** Query must be at least 3 characters long, OR include at least one filter (`vocabulary_ids`, `domain_ids`, or `concept_class_ids`). Short queries without filters are rejected to prevent performance issues.
</ParamField>

<ParamField body="vocabulary_ids" type="array">
  Array of vocabulary IDs to search within

  **Options:** `SNOMED`, `ICD10CM`, `ICD9CM`, `RxNorm`, `LOINC`, `HCPCS`, etc.

  **Default:** All vocabularies
</ParamField>

<ParamField body="domain_ids" type="array">
  Array of domain IDs to filter by

  **Options:** `Condition`, `Drug`, `Procedure`, `Measurement`, `Observation`, etc.
</ParamField>

<ParamField body="concept_class_ids" type="array">
  Array of concept class IDs to filter by

  **Examples:** `Clinical Finding`, `Pharmaceutical Substance`, `Procedure`
</ParamField>

<ParamField body="standard_concepts_only" type="boolean" default={true}>
  Whether to include only standard concepts
</ParamField>

<ParamField body="include_invalid" type="boolean" default={true}>
  Whether to include invalid/deprecated concepts
</ParamField>

<ParamField body="relationship_filters" type="array">
  Array of relationship filter objects

  ```json theme={null}
  [{
    "relationship_id": "Maps to",
    "target_vocabularies": ["SNOMED"],
    "required": true
  }]
  ```
</ParamField>

<ParamField body="date_range" type="object">
  Filter by validity date range

  ```json theme={null}
  {
    "start_date": "2020-01-01",
    "end_date": "2024-12-31"
  }
  ```
</ParamField>

<ParamField body="page" type="integer" default={1}>
  Page number (1-based indexing)
</ParamField>

<ParamField body="page_size" type="integer" default={20}>
  Number of results per page (max: 1000)
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Whether the request was successful
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="data">
    <ResponseField name="concepts" type="array">
      Array of matching concepts

      <Expandable title="concept object">
        <ResponseField name="concept_id" type="integer">
          Unique concept identifier
        </ResponseField>

        <ResponseField name="concept_name" type="string">
          Human-readable concept name
        </ResponseField>

        <ResponseField name="concept_code" type="string">
          Concept code within its vocabulary
        </ResponseField>

        <ResponseField name="vocabulary_id" type="string">
          Source vocabulary identifier
        </ResponseField>

        <ResponseField name="vocabulary_name" type="string">
          Human-readable vocabulary name
        </ResponseField>

        <ResponseField name="domain_id" type="string">
          Concept domain classification
        </ResponseField>

        <ResponseField name="concept_class_id" type="string">
          Concept class within vocabulary
        </ResponseField>

        <ResponseField name="standard_concept" type="string">
          Standard concept designation (S = Standard, C = Classification)
        </ResponseField>

        <ResponseField name="valid_start_date" type="string">
          Date when concept became valid
        </ResponseField>

        <ResponseField name="valid_end_date" type="string">
          Date when concept becomes invalid
        </ResponseField>

        <ResponseField name="invalid_reason" type="string">
          Reason for invalidity (if applicable)
        </ResponseField>

        <ResponseField name="relevance_score" type="number">
          Search relevance score (0.0 to 1.0)
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="facets" type="object">
      Available facets for further filtering

      <Expandable title="facets">
        <ResponseField name="vocabularies" type="array">
          Vocabulary facets with counts
        </ResponseField>

        <ResponseField name="domains" type="array">
          Domain facets with counts
        </ResponseField>

        <ResponseField name="concept_classes" type="array">
          Concept class facets with counts
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="search_metadata" type="object">
      Search execution metadata

      <Expandable title="search_metadata">
        <ResponseField name="query_time_ms" type="integer">
          Query execution time in milliseconds
        </ResponseField>

        <ResponseField name="total_results" type="integer">
          Total number of matching concepts
        </ResponseField>

        <ResponseField name="max_relevance_score" type="number">
          Highest relevance score in results
        </ResponseField>

        <ResponseField name="search_algorithm" type="string">
          Search algorithm used
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta" type="object">
  Response metadata including pagination

  <Expandable title="meta">
    <ResponseField name="request_id" type="string">
      Unique identifier for this request
    </ResponseField>

    <ResponseField name="timestamp" type="string">
      ISO 8601 timestamp of the response
    </ResponseField>

    <ResponseField name="vocab_release" type="string">
      Vocabulary release version used
    </ResponseField>

    <ResponseField name="search" type="object">
      Search metadata

      <Expandable title="search">
        <ResponseField name="query" type="string">
          The search query used
        </ResponseField>

        <ResponseField name="total_results" type="integer">
          Total number of matching concepts
        </ResponseField>

        <ResponseField name="filters_applied" type="object">
          Filters that were applied to the search
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="pagination" type="object">
      Pagination information

      <Expandable title="pagination">
        <ResponseField name="page" type="integer">
          Current page number
        </ResponseField>

        <ResponseField name="page_size" type="integer">
          Number of results per page
        </ResponseField>

        <ResponseField name="total_items" type="integer">
          Total number of results
        </ResponseField>

        <ResponseField name="total_pages" type="integer">
          Total number of pages
        </ResponseField>

        <ResponseField name="has_next" type="boolean">
          Whether a next page exists
        </ResponseField>

        <ResponseField name="has_previous" type="boolean">
          Whether a previous page exists
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Examples

### Basic Search

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.omophub.com/v1/search/advanced" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "diabetes mellitus type 2",
      "page_size": 10
    }'
  ```

  ```python Python theme={null}
  results = client.search.advanced_search(
      query="diabetes mellitus type 2",
      page_size=10
  )

  for concept in results.data:
      print(f"{concept.concept_id}: {concept.concept_name}")
      print(f"  Vocabulary: {concept.vocabulary_id}")
      print(f"  Score: {concept.relevance_score:.3f}")
  ```

  ```javascript JavaScript theme={null}
  const results = await client.search.advancedSearch({
    query: 'diabetes mellitus type 2',
    page_size: 10
  });

  results.data.forEach(concept => {
    console.log(`${concept.concept_id}: ${concept.concept_name}`);
    console.log(`  Vocabulary: ${concept.vocabulary_id}`);
    console.log(`  Score: ${concept.relevance_score.toFixed(3)}`);
  });
  ```

  ```r R theme={null}
  results <- advanced_search_concepts(client,
    query = "diabetes mellitus type 2",
    page_size = 10
  )

  for (i in 1:nrow(results$data$concepts)) {
    concept <- results$data$concepts[i, ]
    cat(paste(concept$concept_id, concept$concept_name, sep = ": "), "\n")
    cat(paste("  Vocabulary:", concept$vocabulary_id), "\n")
    cat(paste("  Score:", round(concept$relevance_score, 3)), "\n")
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Example Response theme={null}
  {
    "success": true,
    "data": {
      "concepts": [
        {
          "concept_id": 201826,
          "concept_name": "Type 2 diabetes mellitus",
          "concept_code": "44054006",
          "vocabulary_id": "SNOMED",
          "vocabulary_name": "Systematized Nomenclature of Medicine Clinical Terms",
          "domain_id": "Condition",
          "concept_class_id": "Clinical Finding",
          "standard_concept": "S",
          "valid_start_date": "1970-01-01",
          "valid_end_date": "2099-12-31",
          "invalid_reason": null,
          "relevance_score": 0.953
        },
        {
          "concept_id": 435216,
          "concept_name": "Diabetes mellitus type 2 in obese",
          "concept_code": "E11.0",
          "vocabulary_id": "ICD10CM",
          "vocabulary_name": "International Classification of Diseases, Tenth Revision, Clinical Modification",
          "domain_id": "Condition",
          "concept_class_id": "4-char billing code",
          "standard_concept": null,
          "valid_start_date": "2015-10-01",
          "valid_end_date": "2099-12-31",
          "invalid_reason": null,
          "relevance_score": 0.847
        }
      ],
      "facets": {
        "vocabularies": [
          {"vocabulary_id": "SNOMED", "vocabulary_name": "SNOMED CT", "count": 45},
          {"vocabulary_id": "ICD10CM", "vocabulary_name": "ICD-10-CM", "count": 23},
          {"vocabulary_id": "ICD9CM", "vocabulary_name": "ICD-9-CM", "count": 12}
        ],
        "domains": [
          {"domain_id": "Condition", "domain_name": "Condition", "count": 67},
          {"domain_id": "Observation", "domain_name": "Observation", "count": 13}
        ],
        "concept_classes": [
          {"concept_class_id": "Clinical Finding", "count": 45},
          {"concept_class_id": "4-char billing code", "count": 23}
        ]
      },
      "search_metadata": {
        "query_time_ms": 127,
        "total_results": 80,
        "max_relevance_score": 0.953,
        "search_algorithm": "full_text_with_ranking"
      }
    },
    "meta": {
      "request_id": "req_adv_search_abc123",
      "timestamp": "2024-01-15T10:30:00Z",
      "vocab_release": "2025.1",
      "search": {
        "query": "diabetes mellitus type 2",
        "total_results": 80,
        "filters_applied": {
          "vocabulary_ids": [],
          "domain_ids": [],
          "standard_concepts_only": true
        }
      },
      "pagination": {
        "page": 1,
        "page_size": 10,
        "total_items": 80,
        "total_pages": 8,
        "has_next": true,
        "has_previous": false
      }
    }
  }
  ```
</ResponseExample>

### Filtered Search

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.omophub.com/v1/search/advanced" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "hypertension",
      "vocabulary_ids": ["SNOMED", "ICD10CM"],
      "domain_ids": ["Condition"],
      "standard_concepts_only": true,
      "date_range": {
        "start_date": "2020-01-01",
        "end_date": "2024-12-31"
      },
      "page_size": 20
    }'
  ```

  ```python Python theme={null}
  results = client.search.advanced_search(
      query="hypertension",
      vocabulary_ids=["SNOMED", "ICD10CM"],
      domain_ids=["Condition"],
      standard_concepts_only=True,
      date_range={
          "start_date": "2020-01-01",
          "end_date": "2024-12-31"
      },
      page_size=20
  )

  print(f"Found {results.meta.pagination.total_items} concepts")
  print(f"Query executed in {results.data.search_metadata.query_time_ms}ms")
  ```

  ```javascript JavaScript theme={null}
  const results = await client.search.advancedSearch({
    query: 'hypertension',
    vocabulary_ids: ['SNOMED', 'ICD10CM'],
    domain_ids: ['Condition'],
    standard_concepts_only: true,
    date_range: {
      start_date: '2020-01-01',
      end_date: '2024-12-31'
    },
    page_size: 20
  });

  console.log(`Found ${results.meta.pagination.total_items} concepts`);
  console.log(`Query executed in ${results.data.search_metadata.query_time_ms}ms`);
  ```

  ```r R theme={null}
  results <- advanced_search_concepts(client,
    query = "hypertension",
    vocabulary_ids = c("SNOMED", "ICD10CM"),
    domain_ids = c("Condition"),
    standard_concepts_only = TRUE,
    date_range = list(
      start_date = "2020-01-01",
      end_date = "2024-12-31"
    ),
    page_size = 20
  )

  cat(paste("Found", results$meta$pagination$total_items, "concepts\n"))
  cat(paste("Query executed in", results$data$search_metadata$query_time_ms, "ms\n"))
  ```
</RequestExample>

### Complex Relationship Filtering

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.omophub.com/v1/search/advanced" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "insulin",
      "vocabulary_ids": ["RxNorm"],
      "domain_ids": ["Drug"],
      "relationship_filters": [
        {
          "relationship_id": "RxNorm has dose form",
          "target_vocabularies": ["RxNorm"],
          "required": true
        }
      ],
      "concept_class_ids": ["Clinical Drug"],
      "page_size": 15
    }'
  ```

  ```python Python theme={null}
  results = client.search.advanced_search(
      query="insulin",
      vocabulary_ids=["RxNorm"],
      domain_ids=["Drug"],
      relationship_filters=[
          {
              "relationship_id": "RxNorm has dose form",
              "target_vocabularies": ["RxNorm"],
              "required": True
          }
      ],
      concept_class_ids=["Clinical Drug"],
      page_size=15
  )

  for concept in results.data:
      print(f"Drug: {concept.concept_name}")
      print(f"  Code: {concept.concept_code}")
      print(f"  Class: {concept.concept_class_id}")
  ```

  ```javascript JavaScript theme={null}
  const results = await client.search.advancedSearch({
    query: 'insulin',
    vocabulary_ids: ['RxNorm'],
    domain_ids: ['Drug'],
    relationship_filters: [
      {
        relationship_id: 'RxNorm has dose form',
        target_vocabularies: ['RxNorm'],
        required: true
      }
    ],
    concept_class_ids: ['Clinical Drug'],
    page_size: 15
  });

  results.data.forEach(concept => {
    console.log(`Drug: ${concept.concept_name}`);
    console.log(`  Code: ${concept.concept_code}`);
    console.log(`  Class: ${concept.concept_class_id}`);
  });
  ```

  ```r R theme={null}
  results <- advanced_search_concepts(client,
    query = "insulin",
    vocabulary_ids = c("RxNorm"),
    domain_ids = c("Drug"),
    relationship_filters = list(
      list(
        relationship_id = "RxNorm has dose form",
        target_vocabularies = c("RxNorm"),
        required = TRUE
      )
    ),
    concept_class_ids = c("Clinical Drug"),
    page_size = 15
  )

  for (i in 1:nrow(results$data$concepts)) {
    concept <- results$data$concepts[i, ]
    cat(paste("Drug:", concept$concept_name), "\n")
    cat(paste("  Code:", concept$concept_code), "\n")
    cat(paste("  Class:", concept$concept_class_id), "\n")
  }
  ```
</RequestExample>

## Search Features

### Full-Text Search

* **Multi-field search**: Searches concept names, synonyms, and descriptions
* **Phrase matching**: Use quotes for exact phrases: `"myocardial infarction"`
* **Wildcard support**: Use `*` for partial matching: `diabet*`
* **Boolean operators**: Use AND, OR, NOT: `diabetes AND type 2`

### Relevance Scoring

Results are ranked by relevance using:

1. **Exact matches**: Exact concept name matches score highest
2. **Phrase matches**: Complete phrase matches in names or synonyms
3. **Term frequency**: Frequency of query terms in concept text
4. **Vocabulary priority**: Standard concepts ranked higher
5. **Clinical relevance**: Healthcare-specific ranking adjustments

### Faceted Search

Use facets to understand result distribution:

```python theme={null}
# Access facets for filtering insights
facets = results.data.facets

print("Available vocabularies:")
for vocab in facets.vocabularies:
    print(f"  {vocab.vocabulary_name}: {vocab.count} concepts")

print("\nAvailable domains:")
for domain in facets.domains:
    print(f"  {domain.domain_name}: {domain.count} concepts")
```

## Performance Tips

1. **Use specific vocabulary\_ids**: Limit search to relevant vocabularies only
2. **Filter by domain\_ids**: Reduce result set with domain filters
3. **Reasonable page sizes**: Use page\_size of 20-100 for best performance
4. **Cache results**: Cache frequently accessed searches
5. **Use standard concepts**: Set `standard_concepts_only: true` for faster queries
6. **Avoid broad queries**: Short queries (\< 3 characters) without filters are rejected. Use more specific terms or add filters for better results.

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Basic Search" icon="magnifying-glass" href="/api-reference/search/basic-search">
    Simple concept search with minimal parameters
  </Card>

  <Card title="Search Autocomplete" icon="keyboard" href="/api-reference/search/search-autocomplete">
    Real-time search suggestions
  </Card>

  <Card title="Similar Concepts" icon="sitemap" href="/api-reference/search/search-similar">
    Find semantically similar concepts
  </Card>

  <Card title="Search Facets" icon="filter" href="/api-reference/search/search-facets">
    Get available search facets
  </Card>
</CardGroup>
