Repository: mlflow/mlflow

Issue:
[BUG] MlflowClient.search_model_versions does not return aliases
### Issues Policy acknowledgement

- [X] I have read and agree to submit bug reports in accordance with the [issues policy](https://www.github.com/mlflow/mlflow/blob/master/ISSUE_POLICY.md)

### Willingness to contribute

Yes. I would be willing to contribute a fix for this bug with guidance from the MLflow community.

### MLflow version

- Client: 2.7.1
- Tracking server: 2.7.1


### System information

- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: MacOS Ventura 13.5
- **Python version**: 3.8.16
- **yarn version, if running the dev UI**:


### Describe the problem

The ModelVersion returned by MlflowClient.search_model_versions does not contain aliases. 

The ModelVersion returned by MlflowClient.get_model_version **does** contain the aliases.

### Tracking information

<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->
```shell

System information: Darwin Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:05 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6000
Python version: 3.8.16
MLflow version: 2.6.0
MLflow module location: /Users/andre/venvs/mlflow-export-import-test/lib/python3.8/site-packages/mlflow/__init__.py
Tracking URI: http://localhost:5010
Registry URI: http://localhost:5010
MLflow environment variables:
  MLFLOW_TRACKING_URI: http://localhost:5010
MLflow dependencies:
  Flask: 2.3.3
  Jinja2: 3.1.2
  alembic: 1.12.0
  click: 8.1.7
  cloudpickle: 2.2.1
  databricks-cli: 0.17.7
  docker: 6.1.3
  entrypoints: 0.4
  gitpython: 3.1.35
  gunicorn: 21.2.0
  importlib-metadata: 6.8.0
  markdown: 3.4.4
  matplotlib: 3.7.2
  numpy: 1.24.4
  packaging: 23.1
  pandas: 2.0.3
  protobuf: 4.24.3
  pyarrow: 12.0.1
  pytz: 2023.3.post1
  pyyaml: 6.0.1
  querystring-parser: 1.2.4
  requests: 2.31.0
  scikit-learn: 1.3.0
  scipy: 1.10.1
  sqlalchemy: 2.0.20
  sqlparse: 0.4.4
```


### Code to reproduce issue

<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->
```
import mlflow
client = mlflow.MlflowClient()

model = "sklearn_wine"
version = "1"

vr = client.get_model_version(name, version)
print(vr.aliases) # :)

vrs = client.search_model_versions(f"name='{name}'")
vr = vrs[0]
print(vr.aliases) # :(

```


### Stack trace

<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->
```
REPLACE_ME
```


### Other info / logs

<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->
```
REPLACE_ME
```


### What component(s) does this bug affect?

- [ ] `area/artifacts`: Artifact stores and artifact logging
- [ ] `area/build`: Build and test infrastructure for MLflow
- [ ] `area/docs`: MLflow documentation pages
- [ ] `area/examples`: Example code
- [ ] `area/gateway`: AI Gateway service, Gateway client APIs, third-party Gateway integrations
- [ ] `area/model-registry`: Model Registry service, APIs, and the fluent client calls for Model Registry
- [ ] `area/models`: MLmodel format, model serialization/deserialization, flavors
- [ ] `area/recipes`: Recipes, Recipe APIs, Recipe configs, Recipe Templates
- [ ] `area/projects`: MLproject format, project running backends
- [ ] `area/scoring`: MLflow Model server, model deployment tools, Spark UDFs
- [ ] `area/server-infra`: MLflow Tracking server backend
- [ ] `area/tracking`: Tracking Service, tracking client APIs, autologging

### What interface(s) does this bug affect?

- [ ] `area/uiux`: Front-end, user experience, plotting, JavaScript, JavaScript dev server
- [ ] `area/docker`: Docker use across MLflow's components, such as MLflow Projects and MLflow Models
- [ ] `area/sqlalchemy`: Use of SQLAlchemy in the Tracking Service or Model Registry
- [ ] `area/windows`: Windows support

### What language(s) does this bug affect?

- [ ] `language/r`: R APIs and clients
- [ ] `language/java`: Java APIs and clients
- [ ] `language/new`: Proposals for new client languages

### What integration(s) does this bug affect?

- [ ] `integrations/azure`: Azure and Azure ML integrations
- [ ] `integrations/sagemaker`: SageMaker integrations
- [ ] `integrations/databricks`: Databricks integrations


Discussion:
@amesar Can you complete the example? Code to register an alias is missing.
File backend works fine:

```python
import mlflow
import tempfile

with tempfile.TemporaryDirectory() as tmpdir:
    mlflow.set_tracking_uri(f"{tmpdir}/mlruns")
    client = mlflow.MlflowClient()

    name = "sklearn_wine"

    with mlflow.start_run():
        mlflow.sklearn.log_model(
            sk_model="model",
            artifact_path="model",
            registered_model_name=name,
        )

    client.set_registered_model_alias(name, "foo", "1")
    vr = client.get_model_version(name, "1")
    print(vr.aliases)  # :)

    vrs = client.search_model_versions(f"name='{name}'")
    print(vrs[0].aliases)  # :(
```

```
['foo']
['foo']
```
DB backend doesn't.

```python
import mlflow
import tempfile

with tempfile.TemporaryDirectory() as tmpdir:
    mlflow.set_tracking_uri(f"sqlite:///{tmpdir}/mlflow.db")
    client = mlflow.MlflowClient()

    name = "sklearn_wine"

    with mlflow.start_run():
        mlflow.sklearn.log_model(
            sk_model="model",
            artifact_path="model",
            registered_model_name=name,
        )

    client.set_registered_model_alias(name, "foo", "1")
    vr = client.get_model_version(name, "1")
    print(vr.aliases)  # :)

    vrs = client.search_model_versions(f"name='{name}'")
    print(vrs[0].aliases)  # :(
```

```
['foo']
[]
```
cc @arpitjasa-db 
We set `aliases` to an empty list here:

https://github.com/mlflow/mlflow/blob/0d5adbd03be636b89f8b087f270f2aaedd19da93/mlflow/store/model_registry/dbmodels/models.py#L114
In `get_model_version`, we call `_populate_model_version_aliases`:

https://github.com/mlflow/mlflow/blob/0d5adbd03be636b89f8b087f270f2aaedd19da93/mlflow/store/model_registry/sqlalchemy_store.py#L833-L845
We can call `_populate_model_version_aliases` for each model version in `search_model_versions`, but I think it's slow when the number of model versions is large.
cc @jerrylian-db @smurching 
<!-- assign-maintainer -->
@mlflow/mlflow-team Please assign a maintainer and start triaging this issue.

Resolving patch:
diff --git a/mlflow/tracking/_model_registry/client.py b/mlflow/tracking/_model_registry/client.py
--- a/mlflow/tracking/_model_registry/client.py
+++ b/mlflow/tracking/_model_registry/client.py
@@ -274,6 +274,10 @@ def search_model_versions(
         """
         Search for model versions in backend that satisfy the filter criteria.
 
+        .. warning:
+
+            The model version search results may not have aliases populated for performance reasons.
+
         :param filter_string: A filter string expression. Currently supports a single filter
                               condition either name of model like ``name = 'model_name'`` or
                               ``run_id = '...'``.
diff --git a/mlflow/tracking/_model_registry/fluent.py b/mlflow/tracking/_model_registry/fluent.py
--- a/mlflow/tracking/_model_registry/fluent.py
+++ b/mlflow/tracking/_model_registry/fluent.py
@@ -234,6 +234,10 @@ def search_model_versions(
     """
     Search for model versions that satisfy the filter criteria.
 
+    .. warning:
+
+        The model version search results may not have aliases populated for performance reasons.
+
     :param filter_string: Filter query string
         (e.g., ``"name = 'a_model_name' and tag.key = 'value1'"``),
         defaults to searching for all model versions. The following identifiers, comparators,


Test patch: