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

# Search Basics

> Step-by-step guide to running your first Cognee search and understanding core parameters

A minimal guide to querying Cognee memory. The current top-level flow uses `cognee.recall()`, while the lower-level `cognee.search()` API remains available when you need direct retriever control.

**Before you start:**

* Complete [Quickstart](../getting-started/quickstart) to understand basic operations
* Ensure you have [LLM Providers](../setup-configuration/llm-providers) configured for LLM-backed retrieval types
* Run `cognee.remember(...)` or otherwise build the graph before querying it
* Keep at least one dataset with `read` permission for the user running the search

## Code in Action

```python theme={null}
await cognee.remember(
    [
        "Alice moved to Paris in 2010. She works as a software engineer.",
        "Bob lives in New York. He is a data scientist.",
        "Alice and Bob met at a conference in 2015.",
    ],
    self_improvement=False,
)

answers = await cognee.recall(query_text="What are the main themes in my data?")
for answer in answers:
    print(answer)
```

<Info>
  When you call `recall()` without an explicit `query_type`, Cognee uses its default auto-routing behavior to choose the best retrieval strategy for the query. To learn more about that routing behavior and the available lower-level search types, see [Recall](/core-concepts/main-operations/recall) and [Search Types](/core-concepts/main-operations/legacy-operations/search).
</Info>

## Parameters Reference

All examples below assume you are inside an async function. Import helpers when needed:

```python theme={null}
from cognee import SearchType
from cognee.modules.engine.models.node_set import NodeSet
```

<AccordionGroup>
  <Accordion title="Core and Prompt Parameters">
    * **`query_text`** (str, required): The question or phrase to search for.
      ```python theme={null}
      answers = await cognee.recall(query_text="Who owns the rollout plan?")
      ```
    * **`query_type`** (SearchType, optional): Sets the retrieval mode. With `recall()`, omitting it enables auto-routing by default; if you pass it explicitly, that strategy is used directly. See [Search Types](/core-concepts/main-operations/legacy-operations/search) for the full list and [Retrievers](/core-concepts/main-operations/legacy-operations/search#retrievers) for how each type maps to a retriever.
      ```python theme={null}
      await cognee.recall(
          query_text="List coding guidelines",
          query_type=SearchType.CODING_RULES,
      )
      ```
    * **`top_k`** (int, optional, default: 10): Maximum number of results to return.
      ```python theme={null}
      await cognee.recall(query_text="Summaries please", top_k=3)
      ```
    * **`system_prompt_path`** (str, optional, default: `"answer_simple_question.txt"`): Path to a prompt file packaged with your project.
      ```python theme={null}
      await cognee.recall(
          query_text="Explain the roadmap in bullet points",
          system_prompt_path="prompts/bullets.txt",
      )
      ```
    * **`system_prompt`** (Optional\[str]): Inline prompt string. Overrides `system_prompt_path` when set.
      ```python theme={null}
      await cognee.recall(
          query_text="Give me a confident answer",
          system_prompt="Answer succinctly and state confidence at the end.",
      )
      ```
    * **`only_context`** (bool, optional, default: False): Skip the LLM completion step and return the retrieved context directly. This avoids the final LLM call and is useful when you want to inspect or reuse the context yourself.

      ```python theme={null}
      import asyncio
      import cognee

      async def main():
          results = await cognee.recall(
              query_text="What did we promise the client?",
              only_context=True,
          )

          if isinstance(results, str):
              # Single-dataset searches may unwrap to a plain string.
              print(results)
          elif results and isinstance(results[0], dict):
              # With access control enabled, each item is grouped by dataset.
              for dataset_result in results:
                  print("Dataset:", dataset_result["dataset_name"])
                  print("Context:", dataset_result["search_result"])
          else:
              # Otherwise, results is typically a list of context strings.
              for context_text in results:
                  print(context_text)

      asyncio.run(main())
      ```

          <Note>
            `only_context=True` works with any search type. For LLM-completion types (`GRAPH_COMPLETION`, `RAG_COMPLETION`, etc.) it returns the text that would have been sent to the LLM. For retrieval-only types (`CHUNKS`, `SUMMARIES`) the behavior is effectively unchanged because no final LLM call is made.
          </Note>
  </Accordion>

  <Accordion title="Advanced Parameters">
    * **`wide_search_top_k`** (int, optional, default: 100): Caps initial candidate retrieval for graph-completion retrievers before ranking. Increase for broader recall on large graphs.
    * **`triplet_distance_penalty`** (float, optional, default: 3.5): Penalty applied in graph retrieval ranking. Controls how triplet distance influences final result ordering.
    * **`retriever_specific_config`** (dict, optional): Per-retriever options. Examples: `response_model` for typed LLM output; `max_iter` for GRAPH\_COMPLETION\_COT; `context_extension_rounds` for GRAPH\_COMPLETION\_CONTEXT\_EXTENSION. See the API reference for full keys.
    * **`verbose`** (bool, optional, default: False): When `true`, results include `text_result`, `context_result`, and `objects_result` fields alongside the answer.
  </Accordion>

  <Accordion title="Node Sets & Filtering Parameters">
    These options scope retrieval to specific node sets. Set both `node_type` and `node_name` to filter — use the same names you passed to `cognee.add(..., node_set=[...])`. See [NodeSets](/core-concepts/further-concepts/node-sets) for background.

    * **`node_type`** (Optional\[Type], optional, default: `NodeSet`): The graph model to search. Leave as `NodeSet` unless you have a custom node model.
    * **`node_name`** (Optional\[List\[str]]): Names of the node sets to include.
          <Accordion title="`node_name` example">
            ```python theme={null}
            from cognee.modules.engine.models.node_set import NodeSet

            await cognee.recall(
                query_text="What discounts did TechSupply offer?",
                node_type=NodeSet,
                node_name=["vendor_conversations"],
            )
            ```
          </Accordion>
    * **`node_name_filter_operator`** (str, optional, default: `"OR"`): Controls how multiple node-set names are combined. `"OR"` returns results connected to **any** of the listed node sets; `"AND"` returns results connected to **all** of them. Case-insensitive.
          <Accordion title="`node_name_filter_operator` example">
            ```python theme={null}
            # OR (default) — results touching any of the listed node sets
            await cognee.recall(
                query_text="Summarize procurement rules",
                node_type=NodeSet,
                node_name=["procurement_policies", "purchase_history"],
                node_name_filter_operator="OR",
            )

            # AND — results that belong to every listed node set
            await cognee.recall(
                query_text="What topics span both domains?",
                node_type=NodeSet,
                node_name=["procurement_policies", "purchase_history"],
                node_name_filter_operator="AND",
            )
            ```
          </Accordion>

    <Note>
      Node-set filtering applies to graph-completion search types (`GRAPH_COMPLETION`, `GRAPH_COMPLETION_COT`, `GRAPH_COMPLETION_CONTEXT_EXTENSION`, `GRAPH_SUMMARY_COMPLETION`, `TEMPORAL`). It has no effect on `CHUNKS`, `SUMMARIES`, `RAG_COMPLETION`, `CYPHER`, or `NATURAL_LANGUAGE`.
    </Note>
  </Accordion>

  <Accordion title="Interaction & History Parameters">
    * **`session_id`** (Optional\[str]): Links this recall to a conversation session. With `recall()`, passing `session_id` by itself makes Cognee search session cache entries first; if nothing matches, it falls through to graph retrieval. When `session_id` is reused across completion-style recalls, previous Q\&A turns can also be included in the prompt context. If omitted while caching is enabled, Cognee writes to `default_session`.
      ```python theme={null}
      # Session-first recall: checks session cache before graph search
      await cognee.recall(
          query_text="Where does Alice live?",
          session_id="conversation_1"
      )

      # Add datasets when you want to force graph-backed recall in session-aware flows
      await cognee.recall(
          query_text="What does she do for work?",
          datasets=["people_demo"],
          session_id="conversation_1"
      )
      ```
      See [Sessions Guide](/guides/sessions) for complete examples. To record feedback on answers, see the [Feedback System](/guides/feedback-system).
  </Accordion>

  <Accordion title="Datasets & Users">
    * **`datasets`** (Optional\[Union\[list\[str], str]]): Limit search to specific dataset names.
      ```python theme={null}
      await cognee.recall(
          query_text="Key risks",
          datasets=["risk_register", "exec_summary"],
      )
      ```

    * **`dataset_ids`** (Optional\[Union\[list\[UUID], UUID]]): Same as `datasets`, using UUIDs instead of names.
      ```python theme={null}
      from uuid import UUID
      await cognee.recall(
          query_text="Customer feedback",
          dataset_ids=[UUID("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")],
      )
      ```

    * **`user`** (Optional\[User]): The user to run the search as. Required for multi-tenant flows or background jobs.

      ```python theme={null}
      from cognee.modules.users.methods import get_user
      user = await get_user(user_id)
      await cognee.recall(query_text="Team OKRs", user=user)
      ```

      **When** `ENABLE_BACKEND_ACCESS_CONTROL=true`:

      * **Result shape**: Searches run only on datasets the user can access. Results are returned as a list of per-dataset objects (`dataset_name`, `dataset_id`, `search_result`). Use `verbose=True` to include `text_result`, `context_result`, and `objects_result` in each item.

      * **Parallel execution**: Multiple datasets are searched concurrently using `asyncio.gather()` — total time is roughly that of the slowest single-dataset search.

      * If no `user` is given, `get_default_user()` is used (created if missing); an error is raised only if this user lacks dataset permissions.

      * If `datasets` is not set, all datasets readable by the user are searched. An error is raised if none are accessible or if a requested dataset is forbidden.

          <Warning>
            `PermissionDeniedError` will be raised unless you search with the same user that added the data or grant access to the default user.
          </Warning>

      **When** `ENABLE_BACKEND_ACCESS_CONTROL=false`:

      * Dataset filters (`datasets`, `dataset_ids`) are ignored — all data is searched.
      * Results are returned as a plain list (e.g. `["answer1", "answer2"]`). If only one dataset is searched and the retriever returns a list, Cognee may unwrap one level for backwards compatibility.
  </Accordion>
</AccordionGroup>

## Citation and Source Tracking

Provenance is available at two levels:

1. **Dataset level** — when `ENABLE_BACKEND_ACCESS_CONTROL=true`, results are wrapped with `dataset_name` and `dataset_id`.
2. **Chunk/summary level** — `CHUNKS` and `SUMMARIES` results include an `id` you can use to look up the item in the graph.

<Note>
  **Search results do not include source file paths.** `raw_data_location` and document `name` live on the `Document` node, not on retrieved chunk/summary payloads. To trace a result back to a file, use dataset provenance or query the graph by `id`.
</Note>

<AccordionGroup>
  <Accordion title="Chunk-level fields (`CHUNKS`)">
    `SearchType.CHUNKS` returns a list of dicts with these fields:

    | Field         | Type  | Description                                                         |
    | ------------- | ----- | ------------------------------------------------------------------- |
    | `id`          | `str` | Chunk UUID                                                          |
    | `text`        | `str` | Raw chunk text                                                      |
    | `chunk_index` | `int` | Position of this chunk within the source document                   |
    | `chunk_size`  | `int` | Token count of this chunk                                           |
    | `cut_type`    | `str` | How the boundary was chosen (`sentence_end`, `paragraph_end`, etc.) |

    ```python theme={null}
    import asyncio
    import cognee
    from cognee import SearchType

    async def main():
        await cognee.add("path/to/policy.pdf", dataset_name="docs")
        await cognee.cognify(datasets=["docs"])

        results = await cognee.recall(
            query_text="What is the refund policy?",
            query_type=SearchType.CHUNKS,
        )

        for chunk in results:
            print("Text:        ", chunk["text"])
            print("Chunk index: ", chunk["chunk_index"])
            print("Chunk ID:    ", chunk["id"])  # UUID for graph lookups
            print()

    asyncio.run(main())
    ```
  </Accordion>

  <Accordion title="Summary-level fields (`SUMMARIES`)">
    `SearchType.SUMMARIES` returns a list of dicts with these fields:

    | Field  | Type  | Description  |
    | ------ | ----- | ------------ |
    | `id`   | `str` | Summary UUID |
    | `text` | `str` | Summary text |

    ```python theme={null}
    results = await cognee.recall(
        query_text="What is the refund policy?",
        query_type=SearchType.SUMMARIES,
    )

    for summary in results:
        print("Summary:", summary["text"])
        print("ID:     ", summary["id"])
    ```
  </Accordion>

  <Accordion title="Dataset-level provenance (access control enabled)">
    When `ENABLE_BACKEND_ACCESS_CONTROL=true`, every result is wrapped with dataset information:

    ```python theme={null}
    import asyncio
    import cognee
    from cognee import SearchType

    async def main():
        results = await cognee.recall(
            query_text="What is the refund policy?",
            query_type=SearchType.CHUNKS,
            datasets=["docs"],
        )

        for dataset_result in results:
            print("Dataset:   ", dataset_result["dataset_name"])
            print("Dataset ID:", dataset_result["dataset_id"])
            for chunk in dataset_result["search_result"]:
                print("  Text:", chunk["text"])
                print("  Chunk ID:", chunk["id"])

    asyncio.run(main())
    ```

    When `ENABLE_BACKEND_ACCESS_CONTROL=false`, results are a plain list with no `dataset_name` or `dataset_id` wrapper.
  </Accordion>

  <Accordion title="Raw source objects (LLM-completion modes)">
    For modes that return a generated answer (`GRAPH_COMPLETION`, `RAG_COMPLETION`, etc.), use `verbose=True` to receive the raw retrieved objects alongside the answer:

    ```python theme={null}
    results = await cognee.recall(
        query_text="Summarize the launch timeline",
        verbose=True,
    )

    for result in results:
        print("Answer:         ", result.get("text_result"))
        print("Context passed: ", result.get("context_result"))
        print("Source objects: ", result.get("objects_result"))
    ```
  </Accordion>
</AccordionGroup>

## Full Example

<Accordion title="Latest guide">
  ```python theme={null}
  import asyncio
  import cognee


  async def main():
      # Start clean (optional in your app)
      await cognee.forget(everything=True)
      # Prepare knowledge base
      await cognee.remember(
          [
              "Alice moved to Paris in 2010. She works as a software engineer.",
              "Bob lives in New York. He is a data scientist.",
              "Alice and Bob met at a conference in 2015.",
          ],
          self_improvement=False,
      )

      # Make sure you've already run cognee.remember(...) so the graph has content
      answers = await cognee.recall(query_text="What are the main themes in my data?")
      for answer in answers:
          print(answer)

  if __name__ == "__main__":
      asyncio.run(main())
  ```
</Accordion>

<Accordion title="Legacy guide">
  ```python theme={null}
  import asyncio
  import cognee

  async def main():
      # Start clean (optional)
      await cognee.prune.prune_data()
      await cognee.prune.prune_system(metadata=True)

      await cognee.add(
          [
              "Alice moved to Paris in 2010. She works as a software engineer.",
              "Bob lives in New York. He is a data scientist.",
              "Alice and Bob met at a conference in 2015.",
          ]
      )
      await cognee.cognify()

      answers = await cognee.recall(query_text="What are the main themes in my data?")
      for answer in answers:
          print(answer)

  if __name__ == "__main__":
      asyncio.run(main())
  ```
</Accordion>

<Note>
  `recall()` is the current high-level retrieval entry point. It routes the query to the best available retrieval strategy and can still use graph-backed search under the hood.
</Note>

## Additional Examples

Additional examples are available on our [GitHub](https://github.com/topoteretes/cognee/tree/main/examples/guides).

<Columns cols={2}>
  <Card title="Custom Prompts" icon="text-wrap" href="/guides/custom-prompts">
    Learn about custom prompts for tailored answers
  </Card>

  <Card title="Permission Snippets" icon="shield" href="/guides/permission-snippets">
    Multi-tenant deployment patterns
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Explore all search types and parameters
  </Card>

  <Card title="Sessions" icon="message-square" href="/guides/sessions">
    Enable conversational memory with sessions
  </Card>

  <Card title="Agent Memory Decorator" icon="bot" href="/core-concepts/further-concepts/agent-memory-decorator">
    Attach retrieval to an agent function boundary
  </Card>
</Columns>
