-
[OPIK-4135] [BE] Fix ambiguous identifier error when filtering experiment items by ID (#4993)
发布于
2026-02-02 11:07:36 +00:00 - [OPIK-4135] [BE] Fix ambiguous identifier error when filtering experiment items by ID
Restructured subqueries in DatasetItemVersionDAO to apply dataset_item_filters
in an inner subquery where only dataset_item_versions exists, making the 'id'
column unambiguous. Previously, the filter was applied after JOINing with
experiment_items_scope which also has an 'id' column, causing ClickHouse to
report AMBIGUOUS_IDENTIFIER error.Added regression test to verify filtering experiment items by dataset item ID
works correctly.- Revision 2: Fix query semantics - apply version filter before LIMIT 1 BY
The initial fix had incorrect query semantics:
- It picked the latest row per ID across ALL versions first
- Then filtered by resolved version
This caused items to disappear if the resolved version had an older row
that satisfied filters but a newer version (across all versions) didn't.The corrected fix:
- Inner subquery does the JOIN and projects columns with unambiguous names
- Includes resolved_version computed from COALESCE(nullIf(e.dataset_version_id, ''), :versionId)
- Outer query applies BOTH version filter AND dataset_item_filters
- THEN applies ORDER BY ... LIMIT 1 BY id
This ensures "latest per id" is scoped to the resolved version only.
- Revision 3: Add experiments_resolved CTE for better index utilization
- Add experiments_resolved CTE to deduplicate experiments table once
- Filter experiments by workspace_id AND dataset_id to use full primary key
- Replace inline experiments JOIN with CTE reference in all queries
- Apply optimization to COUNT, MAIN, and STATS queries
- Revision 4: Optimize experiment items queries with JOIN and proper ORDER BY
- Reorder CTEs: experiments_resolved before experiment_items_scope
- Use INNER JOIN instead of IN subquery for experiment_items filtering
- Update ORDER BY to match table primary key for optimal deduplication:
(workspace_id, experiment_id, dataset_item_id, trace_id, id)
Benefits:
- experiments_resolved uses full primary key index (workspace_id, dataset_id)
- experiment_items filtered early via streaming JOIN
- Deduplication ORDER BY matches ReplacingMergeTree ordering
- Revision 5: Fix experiment items multiplication in dataset_items_resolved CTE
The dataset_items_resolved CTE was joining with experiment_items_scope
which created multiple rows per dataset item (one for each experiment item).
When the main SELECT joined experiment_items_final with dataset_items_resolved
on dataset_item_id, it caused 5x multiplication (one row per experiment item
match in dataset_items_resolved).Fixed by:
- Adding LIMIT 1 BY id at the end of dataset_items_resolved CTE to deduplicate
after the JOIN with experiment_items_scope - Changing inner subquery deduplication from LIMIT 1 BY dataset_version_id, id
to LIMIT 1 BY id for consistency - Re-adding experiment_ids filter to experiment_items_scope for explicit
filtering in addition to the INNER JOIN with experiments_resolved
Test verified: test_evaluate__with_task_span_metrics__mixed_with_regular_metrics__multiple_trials
now passes (expected 10 items, got 10 items instead of 50).- [OPIK-4135] [BE] Fix DatasetsResourceTest experiment creation to use datasetName
Tests were failing because experiments were created with datasetId instead of
datasetName. ExperimentService.create() resolves the dataset from datasetName
via getOrCreateDataset(), so using datasetId caused experiments to be linked
to newly created datasets instead of the test datasets.Changes:
- Add createExperimentForDataset() helper method for proper experiment creation
- Update 7 test methods to use the new helper method
- Fix tests using GENERATOR.generate() to create actual Experiment records
- [OPIK-4135] [BE] Fix MultiValueFeedbackScoresE2ETest to use datasetName for experiment creation
Use datasetName instead of datasetId when creating experiments in the test
to properly link experiments to datasets and enable correct version resolution.- [OPIK-4135] [BE] Remove redundant experiment_ids filter from COUNT query
Remove duplicate experiment_ids filter from experiment_items_scope CTE
in the COUNT query to be consistent with SELECT and STATS queries.
The filter in experiments_resolved CTE is sufficient since experiment_items_scope
already joins with experiments_resolved.下载附件