Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
#
|
|
|
|
|
# Copyright 2025 The InfiniFlow Authors. All Rights Reserved.
|
|
|
|
|
#
|
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
|
#
|
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
#
|
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
|
# limitations under the License.
|
|
|
|
|
#
|
|
|
|
|
|
2026-06-08 04:08:23 -07:00
|
|
|
"""Unit tests for aggregate_table_doc_metadata."""
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
2026-06-08 04:08:23 -07:00
|
|
|
from rag.utils.table_es_metadata import aggregate_table_doc_metadata, merge_table_parser_config_from_kb
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def es_engine(monkeypatch):
|
|
|
|
|
monkeypatch.setattr("rag.utils.table_es_metadata.settings.DOC_ENGINE_INFINITY", False)
|
|
|
|
|
monkeypatch.setattr("rag.utils.table_es_metadata.settings.DOC_ENGINE_OCEANBASE", False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def infinity_engine(monkeypatch):
|
|
|
|
|
monkeypatch.setattr("rag.utils.table_es_metadata.settings.DOC_ENGINE_INFINITY", True)
|
|
|
|
|
monkeypatch.setattr("rag.utils.table_es_metadata.settings.DOC_ENGINE_OCEANBASE", False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _table_task(**kb_extra):
|
|
|
|
|
return {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
|
|
|
|
"table_column_mode": "manual",
|
|
|
|
|
"table_column_roles": {"country": "metadata", "category": "metadata"},
|
|
|
|
|
"table_column_names": ["country", "category"],
|
|
|
|
|
"field_map": {
|
|
|
|
|
"country_tks": "country",
|
|
|
|
|
"category_tks": "category",
|
|
|
|
|
},
|
|
|
|
|
**kb_extra,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestAggregateTableManualDocMetadata:
|
|
|
|
|
def test_aggregate_manual_mode_happy_path(self, es_engine):
|
|
|
|
|
task = _table_task()
|
|
|
|
|
chunks = [
|
|
|
|
|
{
|
|
|
|
|
"country_raw": "Brazil",
|
|
|
|
|
"category_raw": "Economy",
|
|
|
|
|
"country_tks": "x",
|
|
|
|
|
"category_tks": "y",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"country_raw": "Turkey",
|
|
|
|
|
"category_raw": "Disaster",
|
|
|
|
|
"country_tks": "x",
|
|
|
|
|
"category_tks": "y",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"country_raw": "Brazil",
|
|
|
|
|
"category_raw": "Economy",
|
|
|
|
|
"country_tks": "x",
|
|
|
|
|
"category_tks": "y",
|
|
|
|
|
},
|
|
|
|
|
]
|
2026-06-08 04:08:23 -07:00
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
assert out["country"] == ["Brazil", "Turkey"]
|
|
|
|
|
assert out["category"] == ["Economy", "Disaster"]
|
|
|
|
|
|
2026-06-08 04:08:23 -07:00
|
|
|
def test_aggregate_auto_mode_returns_data(self, es_engine):
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
|
|
|
|
"table_column_mode": "auto",
|
2026-06-08 04:08:23 -07:00
|
|
|
"table_column_names": ["country"],
|
|
|
|
|
"field_map": {"country_tks": "country"},
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
},
|
|
|
|
|
}
|
2026-06-08 04:08:23 -07:00
|
|
|
chunks = [{"country_raw": "Brazil", "country_tks": "x"}]
|
|
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
|
|
|
|
assert out == {"country": ["Brazil"]}
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
|
2026-06-08 04:08:23 -07:00
|
|
|
def test_aggregate_auto_mode_all_columns_both(self, es_engine):
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
2026-06-08 04:08:23 -07:00
|
|
|
"table_column_mode": "auto",
|
|
|
|
|
"table_column_names": ["country", "category"],
|
|
|
|
|
"field_map": {"country_tks": "country", "category_tks": "category"},
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
},
|
|
|
|
|
}
|
2026-06-08 04:08:23 -07:00
|
|
|
chunks = [
|
|
|
|
|
{"country_raw": "Brazil", "country_tks": "x", "category_raw": "Economy", "category_tks": "y"},
|
|
|
|
|
{"country_raw": "Turkey", "country_tks": "x", "category_raw": "Disaster", "category_tks": "y"},
|
|
|
|
|
]
|
|
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
|
|
|
|
assert out["country"] == ["Brazil", "Turkey"]
|
|
|
|
|
assert out["category"] == ["Economy", "Disaster"]
|
|
|
|
|
|
|
|
|
|
def test_aggregate_no_mode_defaults_to_auto(self, es_engine):
|
|
|
|
|
"""When table_column_mode is missing, it defaults to 'auto'."""
|
|
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
|
|
|
|
"table_column_names": ["country"],
|
|
|
|
|
"field_map": {"country_tks": "country"},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
chunks = [{"country_raw": "Brazil", "country_tks": "x"}]
|
|
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
|
|
|
|
assert out == {"country": ["Brazil"]}
|
|
|
|
|
|
|
|
|
|
def test_aggregate_no_mode_no_columns_returns_empty(self, es_engine):
|
|
|
|
|
"""No mode and no column names/roles -> empty (nothing to aggregate)."""
|
|
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {},
|
|
|
|
|
}
|
|
|
|
|
assert aggregate_table_doc_metadata([{}], task) == {}
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
|
|
|
|
|
def test_aggregate_no_metadata_columns(self, es_engine):
|
|
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
|
|
|
|
"table_column_mode": "manual",
|
|
|
|
|
"table_column_roles": {"country": "indexing"},
|
|
|
|
|
"table_column_names": ["country"],
|
|
|
|
|
},
|
|
|
|
|
}
|
2026-06-08 04:08:23 -07:00
|
|
|
assert aggregate_table_doc_metadata([{"country_tks": "x"}], task) == {}
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
|
|
|
|
|
def test_aggregate_prefers_raw_over_tks(self, es_engine):
|
|
|
|
|
task = _table_task()
|
|
|
|
|
task["kb_parser_config"]["table_column_roles"] = {"country": "metadata"}
|
|
|
|
|
task["kb_parser_config"]["table_column_names"] = ["country"]
|
|
|
|
|
chunks = [{"country_raw": "Brazil", "country_tks": ["brazil"]}]
|
2026-06-08 04:08:23 -07:00
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
assert out == {"country": ["Brazil"]}
|
|
|
|
|
|
|
|
|
|
def test_aggregate_tks_fallback(self, es_engine):
|
|
|
|
|
task = _table_task()
|
|
|
|
|
task["kb_parser_config"]["table_column_roles"] = {"country": "metadata"}
|
|
|
|
|
task["kb_parser_config"]["table_column_names"] = ["country"]
|
|
|
|
|
chunks = [{"country_tks": ["brazil"]}]
|
2026-06-08 04:08:23 -07:00
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
assert out == {"country": ["brazil"]}
|
|
|
|
|
|
|
|
|
|
def test_aggregate_partial_roles_defaults_to_both(self, es_engine):
|
|
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
|
|
|
|
"table_column_mode": "manual",
|
|
|
|
|
"table_column_roles": {"country": "indexing"},
|
|
|
|
|
"table_column_names": ["country", "city"],
|
|
|
|
|
"field_map": {"city_tks": "city"},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
chunks = [{"city_raw": "SP", "city_tks": "t", "country_tks": "x"}]
|
2026-06-08 04:08:23 -07:00
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
assert out == {"city": ["SP"]}
|
|
|
|
|
assert "country" not in out
|
|
|
|
|
|
|
|
|
|
def test_aggregate_empty_roles_all_columns_both(self, es_engine):
|
|
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
|
|
|
|
"table_column_mode": "manual",
|
|
|
|
|
"table_column_roles": {},
|
|
|
|
|
"table_column_names": ["country", "city"],
|
|
|
|
|
"field_map": {"country_tks": "country", "city_tks": "city"},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
chunks = [
|
|
|
|
|
{"country_raw": "BR", "city_raw": "SP", "country_tks": "x", "city_tks": "y"},
|
|
|
|
|
]
|
2026-06-08 04:08:23 -07:00
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
assert "country" in out and "city" in out
|
|
|
|
|
|
|
|
|
|
def test_aggregate_deduplicates_values(self, es_engine):
|
|
|
|
|
task = _table_task()
|
|
|
|
|
task["kb_parser_config"]["table_column_roles"] = {"country": "metadata"}
|
|
|
|
|
task["kb_parser_config"]["table_column_names"] = ["country"]
|
|
|
|
|
chunks = [
|
|
|
|
|
{"country_raw": "US", "country_tks": "x"},
|
|
|
|
|
{"country_raw": "UK", "country_tks": "y"},
|
|
|
|
|
{"country_raw": "US", "country_tks": "x"},
|
|
|
|
|
]
|
2026-06-08 04:08:23 -07:00
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
assert out["country"] == ["US", "UK"]
|
|
|
|
|
|
|
|
|
|
def test_aggregate_kb_reload_field_map(self, es_engine, monkeypatch):
|
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
|
|
|
|
|
|
class MockKBS:
|
|
|
|
|
@staticmethod
|
|
|
|
|
def get_by_id(kid):
|
|
|
|
|
kb = MagicMock()
|
|
|
|
|
kb.parser_config = {"field_map": {"country_tks": "country"}}
|
|
|
|
|
return True, kb
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
"rag.utils.table_es_metadata._knowledgebase_service_cls",
|
|
|
|
|
lambda: MockKBS,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
|
|
|
|
"table_column_mode": "manual",
|
|
|
|
|
"table_column_roles": {"country": "metadata"},
|
|
|
|
|
"table_column_names": ["country"],
|
|
|
|
|
},
|
|
|
|
|
"kb_id": "kb-1",
|
|
|
|
|
}
|
|
|
|
|
chunks = [{"country_raw": "X", "country_tks": "t"}]
|
2026-06-08 04:08:23 -07:00
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
assert out == {"country": ["X"]}
|
|
|
|
|
|
|
|
|
|
def test_merge_infinity_chunk_data(self, infinity_engine):
|
|
|
|
|
task = {
|
|
|
|
|
"parser_id": "table",
|
|
|
|
|
"parser_config": {},
|
|
|
|
|
"kb_parser_config": {
|
|
|
|
|
"table_column_mode": "manual",
|
|
|
|
|
"table_column_roles": {"country": "both"},
|
|
|
|
|
"table_column_names": ["country"],
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
chunks = [
|
|
|
|
|
{"chunk_data": {"country": "US"}},
|
|
|
|
|
{"chunk_data": {"country": "UK"}},
|
|
|
|
|
]
|
2026-06-08 04:08:23 -07:00
|
|
|
out = aggregate_table_doc_metadata(chunks, task)
|
Feature/table parser column roles (#13710)
### What problem does this PR solve?
The table file parser (CSV/Excel) currently treats all columns
identically — every column is both vectorized (embedded in chunk text)
and stored as filterable metadata. There's no way for users to control
which columns should be searchable by semantic meaning versus which
should only be filterable attributes.
For example, when ingesting a news articles CSV with columns like title,
content, country, category, source, etc., the embedding includes
metadata fields like country: Brazil and source: Reuters in the chunk
text, which dilutes the semantic quality of the embedding without adding
retrieval value.
The RDBMS connector (MySQL/PostgreSQL) already supports content_columns
/ metadata_columns, but this capability was missing for file-based table
ingestion.
This PR adds column-level control (vectorize / metadata / both) for the
table file parser, following RAGFlow's existing patterns.
Backward compatible: Datasets without table_column_roles or with
table_column_mode: auto behave exactly as before (all columns = both).
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
2026-05-11 07:06:04 +05:00
|
|
|
assert out == {"country": ["US", "UK"]}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestMergeTableParserConfigFromKbExtra:
|
|
|
|
|
"""Merge tests also covered in helpers file; keep one explicit case for aggregation module."""
|
|
|
|
|
|
|
|
|
|
def test_merge_preserves_parser_config_when_parser_not_table(self):
|
|
|
|
|
task = {
|
|
|
|
|
"parser_id": "naive",
|
|
|
|
|
"parser_config": {"a": 1},
|
|
|
|
|
"kb_parser_config": {"table_column_mode": "manual"},
|
|
|
|
|
}
|
|
|
|
|
assert merge_table_parser_config_from_kb(task) == {"a": 1}
|