Фильтрация Qdrant с использованием вложенных полей объектовPython

Программы на Python
Anonymous
Фильтрация Qdrant с использованием вложенных полей объектов

Сообщение Anonymous »

У меня есть структура данных в Qdrant, в полезной нагрузке есть что-то вроде этого:

Код: Выделить всё

{
"attributes": [
{
"attribute_value_id": 22003,
"id": 1252,
"key": "Environment",
"value": "Casual/Daily",
},
{
"attribute_value_id": 98763,
"id": 1254,
"key": "Color",
"value": "Multicolored",
},
{
"attribute_value_id": 22040,
"id": 1255,
"key": "Material",
"value": "Polyester",
},
],
"brand": {
"id": 114326,
"logo": None,
"slug": "happiness-istanbul-114326",
"title": "Happiness Istanbul",
},
}
Согласно документации Qdrant, я реализовал фильтрацию по бренду следующим образом:

Код: Выделить всё

filters_list = []
if param_filters:
brands = param_filters.get("brand_params")
if brands:
filter = models.FieldCondition(
key="brand.id",
match=models.MatchAny(any=[int(brand) for brand in brands]),
)
filters_list.append(filter)
search_results = qd_client.search(
query_filter=models.Filter(must=filters_list),
collection_name=f"lang{lang}_products",
query_vector=query_vector,
search_params=models.SearchParams(hnsw_ef=128, exact=False),
limit=limit,
)
Что пока работает. Но все усложняется, когда я пытаюсь фильтровать поле «атрибуты». Как видите, это список словарей, содержащий словари типа:

Код: Выделить всё

{
"attribute_value_id": 22040,
"id": 1255,
"key": "Material",
"value": "Polyester",
}
И фильтр attrs, отправленный из внешнего интерфейса, имеет следующую структуру:

Код: Выделить всё

attrs structure: {"attr_id": [attr_value_ids], "attr_id": [att_value_ids]}
>>> example: {'1237': ['21727', '21759'], '1254': ['52776']}
Как я могу фильтровать, чтобы узнать, существует ли указанный attr_id в параметрах фильтра запроса (здесь это либо 1237, либо 1254) в поле атрибутов и имеет один из атрибутов attr_value_id, указанных в списке (например, ['21727', '21759'] здесь)?
Это то, что я пробовал до сих пор:

Код: Выделить всё

if attrs:
# attrs structure: {"attr_id": [attr_value_ids], "attr_id": [att_value_ids]}
print("attrs from search function:", attrs)
for attr_id, attr_value_ids in attrs.items():
# Convert attribute value IDs to integers
attr_value_ids = [
int(attr_value_id) for attr_value_id in attr_value_ids
]
# Add a filter for each attribute ID and its values
filter = models.FieldCondition(
key=f"attributes.{attr_id}.attr_value_id",
match=models.MatchAny(any=attr_value_ids),
)
filters_list.append(filter)
Проблема в том, что key=f"attributes.{attr_id}.attr_value_id", неверен, и я не знаю, как этого добиться.
ОБНОВЛЕНИЕ: Возможно, на шаг ближе:
Я решил сгладить данные в базе данных, чтобы, возможно, сделать это лучше. Сначала я создал новый файл с именем Flattened_attributes, как показано ниже:

Код: Выделить всё

[
{
"1237": 21720
},
{
"1254": 52791
},
{
"1255": 22044
},
]
Кроме того, перед фильтрацией я использовал тот же подход для фильтров attr, отправленных из внешнего интерфейса:

Код: Выделить всё

        if attrs:
# attrs structure: {"attr_id": [attr_value_ids], "attr_id": [att_value_ids]}
# we need to flatten attrs to filter on payloads
flattened_attr = []
for attr_id, attr_value_ids in attrs.items():
for attr_value_id in attr_value_ids:
flattened_attr.append({attr_id:int(attr_value_id)})

Теперь у меня есть два похожих списка диктовок, и я хочу отфильтровать тех, у кого есть хотя бы один из них, полученный из внешнего интерфейса (

Код: Выделить всё

flattened_attr
).
Существует один тип фильтрации, который мы фильтруем, если значение ключа существует в списке значений, как указано здесь в документации. Но я не знаю, как проверить, существует ли dict в поле Flattened_attributes в базе данных.

Подробнее здесь: https://stackoverflow.com/questions/781 ... ect-fields

Вернуться в «Python»