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

# R SDK - Searching OMOP medical concepts

> Search OMOP medical concepts across SNOMED, ICD-10, LOINC, and RxNorm from the OMOPHub R SDK with keyword, semantic, and filtered queries for OHDSI.

## Basic Search

Search for concepts by text:

```r theme={null}
results <- client$search$basic("diabetes mellitus", page_size = 20)
for (concept in results$data) {
  cat(sprintf("%s: %s\n", concept$concept_id, concept$concept_name))
}
```

### Parameters

| Parameter           | Type      | Default  | Description                                    |
| ------------------- | --------- | -------- | ---------------------------------------------- |
| `query`             | character | required | Search query string                            |
| `vocabulary_ids`    | character | NULL     | Filter by vocabulary IDs                       |
| `domain_ids`        | character | NULL     | Filter by domain IDs                           |
| `concept_class_ids` | character | NULL     | Filter by concept class IDs                    |
| `standard_concept`  | character | NULL     | Filter by standard concept ("S", "C", or NULL) |
| `include_synonyms`  | logical   | FALSE    | Search in synonyms                             |
| `include_invalid`   | logical   | TRUE     | Include invalid concepts                       |
| `min_score`         | numeric   | NULL     | Minimum relevance score (0.0-1.0)              |
| `exact_match`       | logical   | FALSE    | Require exact match                            |
| `page`              | integer   | 1        | Page number (1-based)                          |
| `page_size`         | integer   | 20       | Results per page                               |
| `sort_by`           | character | NULL     | Sort field                                     |
| `sort_order`        | character | NULL     | Sort order ("asc" or "desc")                   |

## Filter by Vocabulary

Restrict search to specific vocabularies:

```r theme={null}
results <- client$search$basic(
  "heart attack",
  vocabulary_ids = "SNOMED"
)

# Multiple vocabularies
results <- client$search$basic(
  "heart attack",
  vocabulary_ids = c("SNOMED", "ICD10CM")
)
```

## Filter by Domain

Search within specific domains:

```r theme={null}
results <- client$search$basic(
  "aspirin",
  domain_ids = "Drug",
  page_size = 10
)
```

## Filter by Concept Class

Search for specific concept classes:

```r theme={null}
results <- client$search$basic(
  "aspirin",
  concept_class_ids = c("Clinical Drug", "Ingredient"),
  page_size = 10
)
```

## Standard Concepts Only

Filter to standard concepts:

```r theme={null}
results <- client$search$basic(
  "diabetes",
  standard_concept = "S",  # "S" = Standard, "C" = Classification
  vocabulary_ids = "SNOMED"
)
```

## Search with Synonyms

Include concept synonyms in search:

```r theme={null}
results <- client$search$basic(
  "heart attack",
  include_synonyms = TRUE,
  vocabulary_ids = "SNOMED"
)
```

## Combined Filters

```r theme={null}
results <- client$search$basic(
  "myocardial infarction",
  vocabulary_ids = "SNOMED",
  domain_ids = "Condition",
  standard_concept = "S",
  include_synonyms = TRUE,
  min_score = 0.5,
  page_size = 20
)
```

## Autocomplete

Get suggestions as the user types:

```r theme={null}
result <- client$search$autocomplete("diab", page_size = 10)
for (suggestion in result$suggestions) {
  print(suggestion$suggestion)
}

# With vocabulary and domain filters
result <- client$search$autocomplete(
  "diab",
  vocabulary_ids = c("SNOMED"),
  domains = c("Condition"),
  page_size = 10
)
```

## Pagination

### Manual Pagination

```r theme={null}
# Get first page
results <- client$search$basic("diabetes", page = 1, page_size = 50)

# Access pagination metadata
pagination <- results$meta
cat(sprintf("Total: %d\n", pagination$total_items))
cat(sprintf("Pages: %d\n", pagination$total_pages))
cat(sprintf("Has next: %s\n", pagination$has_next))

# Get next page
if (isTRUE(pagination$has_next)) {
  results <- client$search$basic("diabetes", page = 2, page_size = 50)
}
```

### Auto-Pagination with basic\_all()

Fetch all results automatically and return as a tibble:

```r theme={null}
# Fetch up to 5 pages of results
all_results <- client$search$basic_all(
  "diabetes",
  page_size = 100,
  max_pages = 5,
  progress = TRUE  # Show progress bar
)

# Results are returned as a tibble
print(nrow(all_results))
print(names(all_results))

# Use with dplyr
library(dplyr)
all_results %>%
  filter(vocabulary_id == "SNOMED") %>%
  select(concept_id, concept_name, domain_id)
```

<Info>
  The `basic_all()` method returns a tibble, making it easy to integrate with
  tidyverse workflows.
</Info>

## Advanced Search

Use advanced search with additional filtering options and facets:

```r theme={null}
results <- client$search$advanced(
  "diabetes",
  vocabulary_ids = c("SNOMED", "ICD10CM"),
  domain_ids = "Condition",
  standard_concepts_only = TRUE,
  page_size = 50
)

# Access results
for (concept in results$data) {
  cat(sprintf("%s: %s\n", concept$concept_id, concept$concept_name))
}

# Access pagination
cat(sprintf("Total: %d\n", results$meta$pagination$total_items))
```

### Advanced Search Parameters

| Parameter                | Type      | Default  | Description                   |
| ------------------------ | --------- | -------- | ----------------------------- |
| `query`                  | character | required | Search query string           |
| `vocabulary_ids`         | character | NULL     | Filter by vocabulary IDs      |
| `domain_ids`             | character | NULL     | Filter by domain IDs          |
| `concept_class_ids`      | character | NULL     | Filter by concept class IDs   |
| `standard_concepts_only` | logical   | FALSE    | Only return standard concepts |
| `include_invalid`        | logical   | TRUE     | Include invalid concepts      |
| `relationship_filters`   | list      | NULL     | Relationship-based filters    |
| `page`                   | integer   | 1        | Page number (1-based)         |
| `page_size`              | integer   | 20       | Results per page              |

### Relationship Filters

Apply relationship-based filtering:

```r theme={null}
results <- client$search$advanced(
  "diabetes",
  relationship_filters = list(
    list(relationship_id = "Is a", concept_id = 4116142)  # Has parent concept
  ),
  standard_concepts_only = TRUE
)
```

## Semantic Search

Search for concepts using natural language with neural embeddings. Semantic search understands meaning, not just keywords.

```r theme={null}
# Basic semantic search
results <- client$search$semantic("heart attack", page_size = 10)

# With filters
results <- client$search$semantic(
  "diabetes mellitus",
  vocabulary_ids = "SNOMED",
  domain_ids = "Condition",
  threshold = 0.5,  # Higher = more similar
  page_size = 20
)

# Access results with similarity scores
for (concept in results$data$results) {
  cat(sprintf("%s: %.2f\n", concept$concept_name, concept$similarity_score))
}
```

### Semantic Search Parameters

| Parameter          | Type       | Default  | Description                     |
| ------------------ | ---------- | -------- | ------------------------------- |
| `query`            | character  | required | Natural language search query   |
| `vocabulary_ids`   | character  | NULL     | Filter by vocabulary IDs        |
| `domain_ids`       | character  | NULL     | Filter by domain IDs            |
| `standard_concept` | "S" \| "C" | NULL     | Filter by standard concept flag |
| `concept_class_id` | character  | NULL     | Filter by concept class         |
| `threshold`        | numeric    | 0.5      | Minimum similarity (0.0-1.0)    |
| `page`             | integer    | 1        | Page number                     |
| `page_size`        | integer    | 20       | Results per page (max 100)      |

### Auto-Pagination with semantic\_all()

Fetch all semantic search results automatically and return as a tibble:

```r theme={null}
# Fetch all results as tibble
all_results <- client$search$semantic_all(
  "diabetes",
  page_size = 100,
  max_pages = 5,
  progress = TRUE
)

# Returns tibble with concept_id, similarity_score, etc.
print(all_results)

# Use with dplyr
library(dplyr)
all_results %>%
  filter(similarity_score > 0.6) %>%
  select(concept_id, concept_name, similarity_score)

# With filters
all_results <- client$search$semantic_all(
  "heart failure",
  vocabulary_ids = "SNOMED",
  threshold = 0.4,
  page_size = 50
)
```

<Info>
  The `semantic_all()` method returns a tibble, making it easy to integrate with
  tidyverse workflows.
</Info>

## Bulk Lexical Search

Search for multiple queries in a single API call (up to 50 queries):

```r theme={null}
results <- client$search$bulk_basic(list(
  list(search_id = "q1", query = "diabetes mellitus"),
  list(search_id = "q2", query = "hypertension"),
  list(search_id = "q3", query = "aspirin")
), defaults = list(vocabulary_ids = list("SNOMED"), page_size = 5))

for (item in results$results) {
  cat(sprintf("%s: %d results (%s)\n", item$search_id, length(item$results), item$status))
}
```

### Bulk Search Parameters

| Parameter                      | Type      | Description                      |
| ------------------------------ | --------- | -------------------------------- |
| `searches`                     | list      | List of search inputs (max 50)   |
| `searches[[i]]$search_id`      | character | Unique ID to match results       |
| `searches[[i]]$query`          | character | Search query                     |
| `searches[[i]]$vocabulary_ids` | list      | Per-search vocabulary filter     |
| `defaults`                     | list      | Shared defaults for all searches |

## Bulk Semantic Search

Search for multiple natural-language queries using neural embeddings (up to 25 queries):

```r theme={null}
results <- client$search$bulk_semantic(list(
  list(search_id = "s1", query = "heart failure treatment options"),
  list(search_id = "s2", query = "type 2 diabetes medication")
), defaults = list(threshold = 0.5, page_size = 10))

for (item in results$results) {
  cat(sprintf("%s: %d results\n", item$search_id, item$result_count))
}
```

### Bulk Semantic Parameters

| Parameter                 | Type      | Description                           |
| ------------------------- | --------- | ------------------------------------- |
| `searches`                | list      | List of search inputs (max 25)        |
| `searches[[i]]$search_id` | character | Unique ID to match results            |
| `searches[[i]]$query`     | character | Natural language query (1-500 chars)  |
| `searches[[i]]$threshold` | numeric   | Per-search similarity threshold (0-1) |
| `defaults`                | list      | Shared defaults for all searches      |

## Find Similar Concepts

Find concepts similar to a reference concept or query. Provide exactly one of: `concept_id`, `concept_name`, or `query`.

```r theme={null}
# By concept ID
similar <- client$search$similar(concept_id = 4329847)  # MI

# By concept name
similar <- client$search$similar(concept_name = "Type 2 diabetes mellitus")

# By natural language query
similar <- client$search$similar(query = "elevated blood sugar")

# With all options
similar <- client$search$similar(
  concept_id = 4329847,
  algorithm = "semantic",  # or "lexical", "hybrid"
  similarity_threshold = 0.7,
  page_size = 50,
  vocabulary_ids = "SNOMED",
  domain_ids = "Condition",
  include_scores = TRUE,
  include_explanations = TRUE
)

# Access results
for (concept in similar$similar_concepts) {
  cat(sprintf("%s: %.2f\n", concept$concept_name, concept$similarity_score))
}
```

### Similar Concepts Parameters

| Parameter              | Type      | Default  | Description                         |
| ---------------------- | --------- | -------- | ----------------------------------- |
| `concept_id`           | integer   | NULL     | Source concept ID                   |
| `concept_name`         | character | NULL     | Source concept name                 |
| `query`                | character | NULL     | Natural language query              |
| `algorithm`            | character | "hybrid" | "semantic", "lexical", or "hybrid"  |
| `similarity_threshold` | numeric   | 0.7      | Minimum similarity (0.0-1.0)        |
| `page_size`            | integer   | 20       | Max results (max 1000)              |
| `vocabulary_ids`       | character | NULL     | Filter by vocabulary                |
| `domain_ids`           | character | NULL     | Filter by domain                    |
| `standard_concept`     | character | NULL     | "S", "C", or "N"                    |
| `include_invalid`      | logical   | NULL     | Include invalid/deprecated concepts |
| `include_scores`       | logical   | NULL     | Include detailed scores             |
| `include_explanations` | logical   | NULL     | Include similarity explanations     |

### Algorithm Comparison

| Algorithm  | Best For                 | Speed  |
| ---------- | ------------------------ | ------ |
| `semantic` | Meaning-based similarity | Slower |
| `lexical`  | Text/string similarity   | Faster |
| `hybrid`   | Balanced approach        | Medium |
