nucliadb 6.3.4.post3680__py3-none-any.whl → 6.3.4.post3694__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- migrations/0032_remove_old_relations.py +73 -0
- nucliadb/backups/restore.py +5 -1
- nucliadb/common/datamanagers/resources.py +0 -14
- nucliadb/common/models_utils/from_proto.py +0 -1
- nucliadb/export_import/utils.py +0 -1
- nucliadb/ingest/orm/brain.py +33 -13
- nucliadb/ingest/orm/broker_message.py +3 -3
- nucliadb/ingest/orm/resource.py +13 -23
- nucliadb/ingest/serialize.py +0 -7
- nucliadb/search/search/graph_merge.py +3 -1
- nucliadb/search/search/merge.py +1 -1
- nucliadb/search/search/query_parser/parsers/graph.py +11 -8
- {nucliadb-6.3.4.post3680.dist-info → nucliadb-6.3.4.post3694.dist-info}/METADATA +6 -6
- {nucliadb-6.3.4.post3680.dist-info → nucliadb-6.3.4.post3694.dist-info}/RECORD +17 -16
- {nucliadb-6.3.4.post3680.dist-info → nucliadb-6.3.4.post3694.dist-info}/WHEEL +0 -0
- {nucliadb-6.3.4.post3680.dist-info → nucliadb-6.3.4.post3694.dist-info}/entry_points.txt +0 -0
- {nucliadb-6.3.4.post3680.dist-info → nucliadb-6.3.4.post3694.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
# Copyright (C) 2021 Bosutech XXI S.L.
|
2
|
+
#
|
3
|
+
# nucliadb is offered under the AGPL v3.0 and as commercial software.
|
4
|
+
# For commercial licensing, contact us at info@nuclia.com.
|
5
|
+
#
|
6
|
+
# AGPL:
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
"""Migration #32
|
22
|
+
|
23
|
+
Remove the old resource relations keys from maindb. It has been moved to user_relations which
|
24
|
+
is stored in object storage.
|
25
|
+
|
26
|
+
"""
|
27
|
+
|
28
|
+
import logging
|
29
|
+
from typing import Optional
|
30
|
+
|
31
|
+
from nucliadb.migrator.context import ExecutionContext
|
32
|
+
|
33
|
+
logger = logging.getLogger(__name__)
|
34
|
+
|
35
|
+
|
36
|
+
async def migrate(context: ExecutionContext) -> None:
|
37
|
+
start: Optional[str] = ""
|
38
|
+
while True:
|
39
|
+
if start is None:
|
40
|
+
break
|
41
|
+
start = await do_batch(context, start)
|
42
|
+
|
43
|
+
|
44
|
+
async def migrate_kb(context: ExecutionContext, kbid: str) -> None:
|
45
|
+
pass
|
46
|
+
|
47
|
+
|
48
|
+
async def do_batch(context: ExecutionContext, start: str) -> Optional[str]:
|
49
|
+
logger.info(f"Running batch from {start}")
|
50
|
+
async with context.kv_driver.transaction(read_only=False) as txn:
|
51
|
+
async with txn.connection.cursor() as cur: # type: ignore
|
52
|
+
# Retrieve a batch of fields
|
53
|
+
await cur.execute(
|
54
|
+
"""
|
55
|
+
SELECT key FROM resources
|
56
|
+
WHERE key ~ '^/kbs/[^/]*/r/[^/]*/relations$'
|
57
|
+
AND key > %s
|
58
|
+
ORDER BY key
|
59
|
+
LIMIT 500""",
|
60
|
+
(start,),
|
61
|
+
)
|
62
|
+
records = await cur.fetchall()
|
63
|
+
if len(records) == 0:
|
64
|
+
return None
|
65
|
+
|
66
|
+
keys = [r[0] for r in records]
|
67
|
+
await cur.execute(
|
68
|
+
"DELETE FROM resources WHERE key = ANY (%s)",
|
69
|
+
(keys,),
|
70
|
+
)
|
71
|
+
await txn.commit()
|
72
|
+
|
73
|
+
return keys[-1]
|
nucliadb/backups/restore.py
CHANGED
@@ -282,7 +282,11 @@ async def restore_search_configurations(context: ApplicationContext, kbid: str,
|
|
282
282
|
bucket=settings.backups_bucket,
|
283
283
|
key=StorageKeys.SEARCH_CONFIGURATIONS.format(backup_id=backup_id),
|
284
284
|
)
|
285
|
-
|
285
|
+
value = raw.getvalue()
|
286
|
+
if not value:
|
287
|
+
# No search configurations to restore
|
288
|
+
return
|
289
|
+
as_dict: dict[str, Any] = json.loads(value)
|
286
290
|
search_configurations: dict[str, SearchConfiguration] = {}
|
287
291
|
for name, data in as_dict.items():
|
288
292
|
config: SearchConfiguration = TypeAdapter(SearchConfiguration).validate_python(data)
|
@@ -41,7 +41,6 @@ KB_RESOURCE_BASIC_FS = "/kbs/{kbid}/r/{uuid}/basic" # Only used on FS driver
|
|
41
41
|
KB_RESOURCE_ORIGIN = "/kbs/{kbid}/r/{uuid}/origin"
|
42
42
|
KB_RESOURCE_EXTRA = "/kbs/{kbid}/r/{uuid}/extra"
|
43
43
|
KB_RESOURCE_SECURITY = "/kbs/{kbid}/r/{uuid}/security"
|
44
|
-
KB_RESOURCE_RELATIONS = "/kbs/{kbid}/r/{uuid}/relations"
|
45
44
|
|
46
45
|
KB_RESOURCE_SLUG_BASE = "/kbs/{kbid}/s/"
|
47
46
|
KB_RESOURCE_SLUG = f"{KB_RESOURCE_SLUG_BASE}{{slug}}"
|
@@ -187,19 +186,6 @@ async def set_security(txn: Transaction, *, kbid: str, rid: str, security: resou
|
|
187
186
|
await txn.set(key, security.SerializeToString())
|
188
187
|
|
189
188
|
|
190
|
-
# Relations
|
191
|
-
|
192
|
-
|
193
|
-
async def get_relations(txn: Transaction, *, kbid: str, rid: str) -> Optional[resources_pb2.Relations]:
|
194
|
-
key = KB_RESOURCE_RELATIONS.format(kbid=kbid, uuid=rid)
|
195
|
-
return await get_kv_pb(txn, key, resources_pb2.Relations)
|
196
|
-
|
197
|
-
|
198
|
-
async def set_relations(txn: Transaction, *, kbid: str, rid: str, relations: resources_pb2.Relations):
|
199
|
-
key = KB_RESOURCE_RELATIONS.format(kbid=kbid, uuid=rid)
|
200
|
-
await txn.set(key, relations.SerializeToString())
|
201
|
-
|
202
|
-
|
203
189
|
# KB resource ids (this functions use internal transactions, breaking the
|
204
190
|
# datamanager contract. We should rethink them at some point)
|
205
191
|
|
@@ -121,7 +121,6 @@ def user_metadata(message: resources_pb2.UserMetadata) -> UserMetadata:
|
|
121
121
|
preserving_proto_field_name=True,
|
122
122
|
including_default_value_fields=True,
|
123
123
|
)
|
124
|
-
value["relations"] = [convert_pb_relation_to_api(rel) for rel in message.relations]
|
125
124
|
return UserMetadata(**value)
|
126
125
|
|
127
126
|
|
nucliadb/export_import/utils.py
CHANGED
nucliadb/ingest/orm/brain.py
CHANGED
@@ -30,6 +30,7 @@ from nucliadb_models.metadata import ResourceProcessingStatus
|
|
30
30
|
from nucliadb_protos import utils_pb2
|
31
31
|
from nucliadb_protos.noderesources_pb2 import IndexParagraph as BrainParagraph
|
32
32
|
from nucliadb_protos.noderesources_pb2 import (
|
33
|
+
IndexRelation,
|
33
34
|
ParagraphMetadata,
|
34
35
|
Representation,
|
35
36
|
ResourceID,
|
@@ -232,15 +233,22 @@ class ResourceBrain:
|
|
232
233
|
full_field_id = ids.FieldId(rid=self.rid, type=field_type, key=field_name).full()
|
233
234
|
self.brain.paragraphs_to_delete.append(full_field_id)
|
234
235
|
|
236
|
+
field_relations = self.brain.field_relations[field_key].relations
|
235
237
|
for relations in metadata.metadata.relations:
|
236
238
|
for relation in relations.relations:
|
237
239
|
self.brain.relations.append(relation)
|
238
240
|
|
241
|
+
index_relation = IndexRelation(relation=relation)
|
242
|
+
if relation.metadata.HasField("data_augmentation_task_id"):
|
243
|
+
index_relation.facets.append(f"/g/da/{relation.metadata.data_augmentation_task_id}")
|
244
|
+
field_relations.append(index_relation)
|
245
|
+
|
239
246
|
def delete_field(self, field_key: str):
|
240
247
|
ftype, fkey = field_key.split("/")
|
241
248
|
full_field_id = ids.FieldId(rid=self.rid, type=ftype, key=fkey).full()
|
242
249
|
self.brain.paragraphs_to_delete.append(full_field_id)
|
243
250
|
self.brain.sentences_to_delete.append(full_field_id)
|
251
|
+
self.brain.relation_fields_to_delete.append(field_key)
|
244
252
|
|
245
253
|
def apply_field_vectors(
|
246
254
|
self,
|
@@ -408,12 +416,14 @@ class ResourceBrain:
|
|
408
416
|
# origin contributors
|
409
417
|
for contrib in origin.colaborators:
|
410
418
|
relationnodeuser = RelationNode(value=contrib, ntype=RelationNode.NodeType.USER)
|
411
|
-
|
412
|
-
Relation
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
419
|
+
relation = Relation(
|
420
|
+
relation=Relation.COLAB,
|
421
|
+
source=relationnodedocument,
|
422
|
+
to=relationnodeuser,
|
423
|
+
)
|
424
|
+
self.brain.relations.append(relation)
|
425
|
+
self.brain.field_relations["a/metadata"].relations.append(
|
426
|
+
IndexRelation(relation=relation)
|
417
427
|
)
|
418
428
|
|
419
429
|
# labels
|
@@ -422,16 +432,22 @@ class ResourceBrain:
|
|
422
432
|
value=f"{classification.labelset}/{classification.label}",
|
423
433
|
ntype=RelationNode.NodeType.LABEL,
|
424
434
|
)
|
425
|
-
|
426
|
-
Relation
|
427
|
-
|
428
|
-
|
429
|
-
to=relation_node_label,
|
430
|
-
)
|
435
|
+
relation = Relation(
|
436
|
+
relation=Relation.ABOUT,
|
437
|
+
source=relationnodedocument,
|
438
|
+
to=relation_node_label,
|
431
439
|
)
|
440
|
+
self.brain.relations.append(relation)
|
441
|
+
self.brain.field_relations["a/metadata"].relations.append(IndexRelation(relation=relation))
|
432
442
|
|
433
443
|
# relations
|
434
|
-
|
444
|
+
for relation in user_relations.relations:
|
445
|
+
self.brain.relations.append(relation)
|
446
|
+
self.brain.field_relations["a/metadata"].relations.append(
|
447
|
+
IndexRelation(relation=relation, facets=["/g/u"])
|
448
|
+
)
|
449
|
+
|
450
|
+
self.brain.relation_fields_to_delete.append("a/metadata")
|
435
451
|
|
436
452
|
def _set_resource_labels(self, basic: Basic, origin: Optional[Origin]):
|
437
453
|
if origin is not None:
|
@@ -507,6 +523,7 @@ class ResourceBrain:
|
|
507
523
|
relation.CopyFrom(base_classification_relation)
|
508
524
|
relation.to.value = label
|
509
525
|
self.brain.relations.append(relation)
|
526
|
+
self.brain.field_relations[field_key].relations.append(IndexRelation(relation=relation))
|
510
527
|
|
511
528
|
# Data Augmentation + Processor entities
|
512
529
|
base_entity_relation = Relation(
|
@@ -534,6 +551,7 @@ class ResourceBrain:
|
|
534
551
|
relation.to.value = entity_text
|
535
552
|
relation.to.subtype = entity_label
|
536
553
|
self.brain.relations.append(relation)
|
554
|
+
self.brain.field_relations[field_key].relations.append(IndexRelation(relation=relation))
|
537
555
|
|
538
556
|
# Legacy processor entities
|
539
557
|
# TODO: Remove once processor doesn't use this anymore and remove the positions and ner fields from the message
|
@@ -553,6 +571,7 @@ class ResourceBrain:
|
|
553
571
|
relation.to.value = entity
|
554
572
|
relation.to.subtype = klass
|
555
573
|
self.brain.relations.append(relation)
|
574
|
+
self.brain.field_relations[field_key].relations.append(IndexRelation(relation=relation))
|
556
575
|
|
557
576
|
def apply_field_labels(
|
558
577
|
self,
|
@@ -609,6 +628,7 @@ class ResourceBrain:
|
|
609
628
|
to=relation_node_entity,
|
610
629
|
)
|
611
630
|
self.brain.relations.append(rel)
|
631
|
+
self.brain.field_relations[field_key].relations.append(IndexRelation(relation=rel))
|
612
632
|
for paragraph_annotation in basic_user_fieldmetadata.paragraphs:
|
613
633
|
for classification in paragraph_annotation.classifications:
|
614
634
|
if not classification.cancelled_by_user:
|
@@ -66,10 +66,10 @@ class _BrokerMessageBuilder:
|
|
66
66
|
origin = await resource.get_origin()
|
67
67
|
if origin is not None:
|
68
68
|
self.bm.origin.CopyFrom(origin)
|
69
|
-
|
69
|
+
|
70
|
+
relations = await resource.get_user_relations()
|
70
71
|
if relations is not None:
|
71
|
-
|
72
|
-
self.bm.relations.append(relation)
|
72
|
+
self.bm.user_relations.CopyFrom(relations)
|
73
73
|
|
74
74
|
fields = await resource.get_fields(force=True)
|
75
75
|
for (type_id, field_id), field in fields.items():
|
nucliadb/ingest/orm/resource.py
CHANGED
@@ -67,7 +67,6 @@ from nucliadb_protos.resources_pb2 import Extra as PBExtra
|
|
67
67
|
from nucliadb_protos.resources_pb2 import Metadata as PBMetadata
|
68
68
|
from nucliadb_protos.resources_pb2 import Origin as PBOrigin
|
69
69
|
from nucliadb_protos.resources_pb2 import Relations as PBRelations
|
70
|
-
from nucliadb_protos.utils_pb2 import Relation as PBRelation
|
71
70
|
from nucliadb_protos.writer_pb2 import BrokerMessage
|
72
71
|
from nucliadb_utils.storages.storage import Storage
|
73
72
|
|
@@ -284,24 +283,6 @@ class Resource:
|
|
284
283
|
self.security = payload
|
285
284
|
|
286
285
|
# Relations
|
287
|
-
async def get_relations(self) -> Optional[PBRelations]:
|
288
|
-
if self.relations is None:
|
289
|
-
relations = await datamanagers.resources.get_relations(
|
290
|
-
self.txn, kbid=self.kb.kbid, rid=self.uuid
|
291
|
-
)
|
292
|
-
self.relations = relations
|
293
|
-
return self.relations
|
294
|
-
|
295
|
-
async def set_relations(self, payload: list[PBRelation]):
|
296
|
-
relations = PBRelations()
|
297
|
-
for relation in payload:
|
298
|
-
relations.relations.append(relation)
|
299
|
-
await datamanagers.resources.set_relations(
|
300
|
-
self.txn, kbid=self.kb.kbid, rid=self.uuid, relations=relations
|
301
|
-
)
|
302
|
-
self.modified = True
|
303
|
-
self.relations = relations
|
304
|
-
|
305
286
|
async def get_user_relations(self) -> PBRelations:
|
306
287
|
if self.user_relations is None:
|
307
288
|
sf = self.storage.user_relations(self.kb.kbid, self.uuid)
|
@@ -536,6 +517,7 @@ class Resource:
|
|
536
517
|
deleted=message.delete_fields, # type: ignore
|
537
518
|
errors=message.errors, # type: ignore
|
538
519
|
)
|
520
|
+
self.modified = True
|
539
521
|
|
540
522
|
@processor_observer.wrap({"type": "apply_fields_status"})
|
541
523
|
async def apply_fields_status(self, message: BrokerMessage, updated_fields: list[FieldID]):
|
@@ -593,6 +575,7 @@ class Resource:
|
|
593
575
|
# status to the default value, which is PROCESSING. This covers the case of new field creation.
|
594
576
|
|
595
577
|
await field_obj.set_status(status)
|
578
|
+
self.modified = True
|
596
579
|
|
597
580
|
async def update_status(self):
|
598
581
|
field_ids = await self.get_all_field_ids(for_update=False)
|
@@ -681,14 +664,11 @@ class Resource:
|
|
681
664
|
for field_large_metadata in message.field_large_metadata:
|
682
665
|
await self._apply_field_large_metadata(field_large_metadata)
|
683
666
|
|
684
|
-
for relation in message.relations:
|
685
|
-
self.indexer.brain.relations.append(relation)
|
686
|
-
await self.set_relations(message.relations) # type: ignore
|
687
|
-
|
688
667
|
# Basic proto may have been modified in some apply functions but we only
|
689
668
|
# want to set it once
|
690
669
|
if self.basic != previous_basic:
|
691
670
|
await self.set_basic(self.basic)
|
671
|
+
self.modified = True
|
692
672
|
|
693
673
|
async def _apply_extracted_text(self, extracted_text: ExtractedTextWrapper):
|
694
674
|
field_obj = await self.get_field(
|
@@ -698,15 +678,18 @@ class Resource:
|
|
698
678
|
self._modified_extracted_text.append(
|
699
679
|
extracted_text.field,
|
700
680
|
)
|
681
|
+
self.modified = True
|
701
682
|
|
702
683
|
async def _apply_question_answers(self, question_answers: FieldQuestionAnswerWrapper):
|
703
684
|
field = question_answers.field
|
704
685
|
field_obj = await self.get_field(field.field, field.field_type, load=False)
|
705
686
|
await field_obj.set_question_answers(question_answers)
|
687
|
+
self.modified = True
|
706
688
|
|
707
689
|
async def _delete_question_answers(self, field_id: FieldID):
|
708
690
|
field_obj = await self.get_field(field_id.field, field_id.field_type, load=False)
|
709
691
|
await field_obj.delete_question_answers()
|
692
|
+
self.modified = True
|
710
693
|
|
711
694
|
async def _apply_link_extracted_data(self, link_extracted_data: LinkExtractedData):
|
712
695
|
assert self.basic is not None
|
@@ -722,6 +705,7 @@ class Resource:
|
|
722
705
|
maybe_update_basic_icon(self.basic, "application/stf-link")
|
723
706
|
|
724
707
|
maybe_update_basic_summary(self.basic, link_extracted_data.description)
|
708
|
+
self.modified = True
|
725
709
|
|
726
710
|
async def maybe_update_resource_title_from_link(self, link_extracted_data: LinkExtractedData):
|
727
711
|
"""
|
@@ -736,6 +720,7 @@ class Resource:
|
|
736
720
|
return
|
737
721
|
title = link_extracted_data.title
|
738
722
|
await self.update_resource_title(title)
|
723
|
+
self.modified = True
|
739
724
|
|
740
725
|
async def update_resource_title(self, computed_title: str) -> None:
|
741
726
|
assert self.basic is not None
|
@@ -760,6 +745,7 @@ class Resource:
|
|
760
745
|
fcmw.metadata.metadata.paragraphs.append(paragraph)
|
761
746
|
|
762
747
|
await field.set_field_metadata(fcmw)
|
748
|
+
self.modified = True
|
763
749
|
|
764
750
|
async def _apply_file_extracted_data(self, file_extracted_data: FileExtractedData):
|
765
751
|
assert self.basic is not None
|
@@ -772,6 +758,7 @@ class Resource:
|
|
772
758
|
await field_file.set_file_extracted_data(file_extracted_data)
|
773
759
|
maybe_update_basic_icon(self.basic, file_extracted_data.icon)
|
774
760
|
maybe_update_basic_thumbnail(self.basic, file_extracted_data.file_thumbnail)
|
761
|
+
self.modified = True
|
775
762
|
|
776
763
|
async def _should_update_resource_title_from_file_metadata(self) -> bool:
|
777
764
|
"""
|
@@ -862,6 +849,7 @@ class Resource:
|
|
862
849
|
maybe_update_basic_thumbnail(self.basic, field_metadata.metadata.metadata.thumbnail)
|
863
850
|
|
864
851
|
add_field_classifications(self.basic, field_metadata)
|
852
|
+
self.modified = True
|
865
853
|
|
866
854
|
async def _apply_extracted_vectors(
|
867
855
|
self,
|
@@ -906,6 +894,7 @@ class Resource:
|
|
906
894
|
vo = await field_obj.set_vectors(
|
907
895
|
field_vectors, vectorset.vectorset_id, vectorset.storage_key_kind
|
908
896
|
)
|
897
|
+
self.modified = True
|
909
898
|
if vo is None:
|
910
899
|
raise AttributeError("Vector object not found on set_vectors")
|
911
900
|
|
@@ -934,6 +923,7 @@ class Resource:
|
|
934
923
|
load=False,
|
935
924
|
)
|
936
925
|
await field_obj.set_large_field_metadata(field_large_metadata)
|
926
|
+
self.modified = True
|
937
927
|
|
938
928
|
def generate_field_id(self, field: FieldID) -> str:
|
939
929
|
return f"{FIELD_TYPE_PB_TO_STR[field.field_type]}/{field.field}"
|
nucliadb/ingest/serialize.py
CHANGED
@@ -233,13 +233,6 @@ async def managed_serialize(
|
|
233
233
|
from_proto.relation(rel) for rel in relations.relations
|
234
234
|
]
|
235
235
|
|
236
|
-
if ResourceProperties.RELATIONS in show:
|
237
|
-
await orm_resource.get_relations()
|
238
|
-
if orm_resource.relations is not None:
|
239
|
-
resource.relations = [
|
240
|
-
from_proto.relation(relation) for relation in orm_resource.relations.relations
|
241
|
-
]
|
242
|
-
|
243
236
|
if ResourceProperties.ORIGIN in show:
|
244
237
|
await orm_resource.get_origin()
|
245
238
|
if orm_resource.origin is not None:
|
@@ -19,7 +19,7 @@
|
|
19
19
|
#
|
20
20
|
|
21
21
|
|
22
|
-
from nucliadb.common.models_utils.from_proto import RelationNodeTypePbMap
|
22
|
+
from nucliadb.common.models_utils.from_proto import RelationNodeTypePbMap, RelationTypePbMap
|
23
23
|
from nucliadb_models.graph import responses as graph_responses
|
24
24
|
from nucliadb_models.graph.responses import (
|
25
25
|
GraphNodesSearchResponse,
|
@@ -45,6 +45,7 @@ def build_graph_response(results: list[nodereader_pb2.GraphSearchResponse]) -> G
|
|
45
45
|
),
|
46
46
|
relation=graph_responses.GraphRelation(
|
47
47
|
label=relation.label,
|
48
|
+
type=RelationTypePbMap[relation.relation_type],
|
48
49
|
),
|
49
50
|
destination=graph_responses.GraphNode(
|
50
51
|
value=destination.value,
|
@@ -84,6 +85,7 @@ def build_graph_relations_response(
|
|
84
85
|
relations.append(
|
85
86
|
graph_responses.GraphRelation(
|
86
87
|
label=relation.label,
|
88
|
+
type=RelationTypePbMap[relation.relation_type],
|
87
89
|
)
|
88
90
|
)
|
89
91
|
response = GraphRelationsSearchResponse(relations=relations)
|
nucliadb/search/search/merge.py
CHANGED
@@ -488,7 +488,7 @@ def _merge_relations_results(
|
|
488
488
|
for relation in relation_response.subgraph.relations:
|
489
489
|
origin = relation.source
|
490
490
|
destination = relation.to
|
491
|
-
relation_type = RelationTypePbMap[relation.relation]
|
491
|
+
relation_type = RelationTypePbMap[relation.relation] # type: ignore
|
492
492
|
relation_label = relation.relation_label
|
493
493
|
metadata = relation.metadata if relation.HasField("metadata") else None
|
494
494
|
# If only_with_metadata is True, we check that metadata for the relation is not None
|
@@ -19,7 +19,7 @@
|
|
19
19
|
#
|
20
20
|
|
21
21
|
|
22
|
-
from nucliadb.common.models_utils.from_proto import RelationNodeTypeMap
|
22
|
+
from nucliadb.common.models_utils.from_proto import RelationNodeTypeMap, RelationTypeMap
|
23
23
|
from nucliadb.search.search.query_parser.models import GraphRetrieval
|
24
24
|
from nucliadb_models.graph import requests as graph_requests
|
25
25
|
from nucliadb_protos import nodereader_pb2
|
@@ -71,9 +71,7 @@ def _parse_path_query(expr: graph_requests.GraphPathQuery) -> nodereader_pb2.Gra
|
|
71
71
|
_set_node_to_pb(expr.destination, pb.path.destination)
|
72
72
|
|
73
73
|
if expr.relation is not None:
|
74
|
-
relation
|
75
|
-
if relation.label is not None:
|
76
|
-
pb.path.relation.value = relation.label
|
74
|
+
_set_relation_to_pb(expr.relation, pb.path.relation)
|
77
75
|
|
78
76
|
pb.path.undirected = expr.undirected
|
79
77
|
|
@@ -88,8 +86,7 @@ def _parse_path_query(expr: graph_requests.GraphPathQuery) -> nodereader_pb2.Gra
|
|
88
86
|
pb.path.undirected = True
|
89
87
|
|
90
88
|
elif isinstance(expr, graph_requests.Relation):
|
91
|
-
|
92
|
-
pb.path.relation.value = expr.label
|
89
|
+
_set_relation_to_pb(expr, pb.path.relation)
|
93
90
|
|
94
91
|
else: # pragma: nocover
|
95
92
|
# This is a trick so mypy generates an error if this branch can be reached,
|
@@ -142,8 +139,7 @@ def _parse_relation_query(
|
|
142
139
|
pb.bool_not.CopyFrom(_parse_relation_query(expr.operand))
|
143
140
|
|
144
141
|
elif isinstance(expr, graph_requests.Relation):
|
145
|
-
|
146
|
-
pb.path.relation.value = expr.label
|
142
|
+
_set_relation_to_pb(expr, pb.path.relation)
|
147
143
|
|
148
144
|
else: # pragma: nocover
|
149
145
|
# This is a trick so mypy generates an error if this branch can be reached,
|
@@ -172,3 +168,10 @@ def _set_node_to_pb(node: graph_requests.GraphNode, pb: nodereader_pb2.GraphQuer
|
|
172
168
|
|
173
169
|
if node.group is not None:
|
174
170
|
pb.node_subtype = node.group
|
171
|
+
|
172
|
+
|
173
|
+
def _set_relation_to_pb(relation: graph_requests.GraphRelation, pb: nodereader_pb2.GraphQuery.Relation):
|
174
|
+
if relation.label is not None:
|
175
|
+
pb.value = relation.label
|
176
|
+
if relation.type is not None:
|
177
|
+
pb.relation_type = RelationTypeMap[relation.type]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: nucliadb
|
3
|
-
Version: 6.3.4.
|
3
|
+
Version: 6.3.4.post3694
|
4
4
|
Summary: NucliaDB
|
5
5
|
Author-email: Nuclia <nucliadb@nuclia.com>
|
6
6
|
License: AGPL
|
@@ -20,11 +20,11 @@ Classifier: Programming Language :: Python :: 3.12
|
|
20
20
|
Classifier: Programming Language :: Python :: 3 :: Only
|
21
21
|
Requires-Python: <4,>=3.9
|
22
22
|
Description-Content-Type: text/markdown
|
23
|
-
Requires-Dist: nucliadb-telemetry[all]>=6.3.4.
|
24
|
-
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.4.
|
25
|
-
Requires-Dist: nucliadb-protos>=6.3.4.
|
26
|
-
Requires-Dist: nucliadb-models>=6.3.4.
|
27
|
-
Requires-Dist: nidx-protos>=6.3.4.
|
23
|
+
Requires-Dist: nucliadb-telemetry[all]>=6.3.4.post3694
|
24
|
+
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.4.post3694
|
25
|
+
Requires-Dist: nucliadb-protos>=6.3.4.post3694
|
26
|
+
Requires-Dist: nucliadb-models>=6.3.4.post3694
|
27
|
+
Requires-Dist: nidx-protos>=6.3.4.post3694
|
28
28
|
Requires-Dist: nucliadb-admin-assets>=1.0.0.post1224
|
29
29
|
Requires-Dist: nuclia-models>=0.24.2
|
30
30
|
Requires-Dist: uvicorn
|
@@ -27,6 +27,7 @@ migrations/0028_extracted_vectors_reference.py,sha256=49DHCIlBpjofU8cYVHTdWv0EBI
|
|
27
27
|
migrations/0029_backfill_field_status.py,sha256=QWF69n1da9lpRnbEpgbqPjSQ-Wfn6rMC7Enz6bBYGt4,5663
|
28
28
|
migrations/0030_label_deduplication.py,sha256=y14TxtCMi3-TBMz_eZoyyPDHNlZb29taJujlDuHumsA,2008
|
29
29
|
migrations/0031_languages_deduplication.py,sha256=o6va6lP3oTRT1uSzp5MIhHHBFbhCxSZ-oNlXXpiAdUo,2340
|
30
|
+
migrations/0032_remove_old_relations.py,sha256=ZaswhmRRsLgw6DVYVdT7cP-gdBf4X3PL9fklUXrmSD0,2318
|
30
31
|
migrations/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
31
32
|
migrations/pg/0001_bootstrap.py,sha256=Fsqkeof50m7fKiJN05kmNEMwiKDlOrAgcAS5sLLkutA,1256
|
32
33
|
migrations/pg/0002_catalog.py,sha256=Rsleecu351Ty19kYZgOpqX5G3MEAY8nMxCJrAeuS2Mw,1690
|
@@ -44,7 +45,7 @@ nucliadb/backups/const.py,sha256=AaIsBB04WerR-V6t8NoCUScxO1ojMYJzfHgdkF2qh4M,201
|
|
44
45
|
nucliadb/backups/create.py,sha256=D0MEpIYu74AhbZXeybinQo8cm_A2-T9JxDGLrp5lavA,12507
|
45
46
|
nucliadb/backups/delete.py,sha256=AAs-WP-ujejj6c1LJgiMn7Ht67N_j0a1sKQlUepHpEA,2659
|
46
47
|
nucliadb/backups/models.py,sha256=-hITU4Mv6AxePu12toBu_fjpEv6vVGcwNVxV22O9jQA,1273
|
47
|
-
nucliadb/backups/restore.py,sha256=
|
48
|
+
nucliadb/backups/restore.py,sha256=Jzp4mrJon3EEl8sqr0KZ5bhlhDXwIYnRD9RsBAFyEyc,11502
|
48
49
|
nucliadb/backups/settings.py,sha256=SyzsInj1BRbBI0atg5IXWbMbOZ_eVg4eSQ3IcnUhCxQ,1357
|
49
50
|
nucliadb/backups/tasks.py,sha256=WkL1LgdYBHbV_A5ilyYv5p3zmXwxH68TDudytN5f7zk,4225
|
50
51
|
nucliadb/backups/utils.py,sha256=_Vogjqcru5oqNZM-bZ0q7Ju79Bv1PD-LVFEa7Z-Q13I,1261
|
@@ -76,7 +77,7 @@ nucliadb/common/datamanagers/fields.py,sha256=9KqBzTssAT68FR5hd17Xu_CSwAYdKFuYic
|
|
76
77
|
nucliadb/common/datamanagers/kb.py,sha256=P7EhF4tApIUG2jw_HH1oMufTKG9__kuOLKnrCNGbDM4,6156
|
77
78
|
nucliadb/common/datamanagers/labels.py,sha256=Zm0GQpSPoGXEEysUY7VsDIcyKSIIQsMVphj23IyM9_c,4502
|
78
79
|
nucliadb/common/datamanagers/processing.py,sha256=ByxdZzdbAfJGqC6__mY-zryjk040TyQfcUq3rxujeoY,1587
|
79
|
-
nucliadb/common/datamanagers/resources.py,sha256=
|
80
|
+
nucliadb/common/datamanagers/resources.py,sha256=cuwcVL-GEjS1VHigJtz5SG_dRhl09UADQ9MSYOOqs70,10779
|
80
81
|
nucliadb/common/datamanagers/rollover.py,sha256=c_DE3jtZusNL_9aOVjHOB9PV5OSVg7GJ5J-Ny0goHBE,7833
|
81
82
|
nucliadb/common/datamanagers/search_configurations.py,sha256=O-8eW43CE46GcxO6TB5hpi27NBguv4BL4SI1vLlN8os,2463
|
82
83
|
nucliadb/common/datamanagers/synonyms.py,sha256=zk3GEH38KF5vV_VcuL6DCg-2JwgXJfQl7Io6VPqv2cw,1566
|
@@ -101,7 +102,7 @@ nucliadb/common/maindb/local.py,sha256=uE9DIQX1yCNHNN8Tx4fPgSiuTtWpQhlfWkMJ8QZPa
|
|
101
102
|
nucliadb/common/maindb/pg.py,sha256=FNq2clckJYj4Te-1svjQblqGoAF5OwJ5nwz2JtxD0d4,13645
|
102
103
|
nucliadb/common/maindb/utils.py,sha256=zWLs82rWEVhpc1dYvdqTZiAcjZroB6Oo5MQaxMeFuKk,3301
|
103
104
|
nucliadb/common/models_utils/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
104
|
-
nucliadb/common/models_utils/from_proto.py,sha256=
|
105
|
+
nucliadb/common/models_utils/from_proto.py,sha256=yYn5vg4SKgB57RKOmeqzfD8VfmjKSSr4UNhw-Vvb4vs,15891
|
105
106
|
nucliadb/common/models_utils/to_proto.py,sha256=97JvOR_3odu50YvzLa2CERfEN3w_QPmAVcCJwJB5m5A,2438
|
106
107
|
nucliadb/export_import/__init__.py,sha256=y-Is0Bxa8TMV6UiOW0deC_D3U465P65CQ5RjBjIWnow,932
|
107
108
|
nucliadb/export_import/datamanager.py,sha256=xL8b0xvk45q6wx1l7J32JgPmpyjnF6fKiJi2F2B_UQY,6968
|
@@ -110,13 +111,13 @@ nucliadb/export_import/exporter.py,sha256=k2QVx1EjqFlDYiggriWiEJzwtMXzHbldsqWdpG
|
|
110
111
|
nucliadb/export_import/importer.py,sha256=v5cq9Nn8c2zrY_K_00mydR52f8mdFxR7tLdtNLQ0qvk,4229
|
111
112
|
nucliadb/export_import/models.py,sha256=dbjScNkiMRv4X3Ktudy1JRliD25bfoDTy3JmEZgQSCc,2121
|
112
113
|
nucliadb/export_import/tasks.py,sha256=DWbdqY97ffoyfipelGXz3Jqz1iam6JCjQSh367Fc3NA,2947
|
113
|
-
nucliadb/export_import/utils.py,sha256=
|
114
|
+
nucliadb/export_import/utils.py,sha256=9M81mrFV7FyBcWjsq4KrqfLIXFYbt9_vD1mkY31z4gs,22819
|
114
115
|
nucliadb/ingest/__init__.py,sha256=fsw3C38VP50km3R-nHL775LNGPpJ4JxqXJ2Ib1f5SqE,1011
|
115
116
|
nucliadb/ingest/app.py,sha256=TaVgh5B2riFVmcsrbPb7a5YCzmnybjx-NK0BXgTwGAY,7535
|
116
117
|
nucliadb/ingest/partitions.py,sha256=2NIhMYbNT0TNBL6bX1UMSi7vxFGICstCKEqsB0TXHOE,2410
|
117
118
|
nucliadb/ingest/processing.py,sha256=7NNoVxbSwsRdbo5goqVSrUc_QXZRVfOT_jZPzrmbxJQ,22207
|
118
119
|
nucliadb/ingest/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
119
|
-
nucliadb/ingest/serialize.py,sha256
|
120
|
+
nucliadb/ingest/serialize.py,sha256=-TIjibJTbMqAowzRvyrG3R209vKqBZqXpdrQL9Dq4lo,16135
|
120
121
|
nucliadb/ingest/settings.py,sha256=0B-wQNa8FLqtNcQgRzh-fuIuGptM816XHcbH1NQKfmE,3050
|
121
122
|
nucliadb/ingest/utils.py,sha256=l1myURu3r8oA11dx3GpHw-gNTUc1AFX8xdPm9Lgl2rA,2275
|
122
123
|
nucliadb/ingest/consumer/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
@@ -137,13 +138,13 @@ nucliadb/ingest/fields/generic.py,sha256=elgtqv15aJUq3zY7X_g0bli_2BpcwPArVvzhe54
|
|
137
138
|
nucliadb/ingest/fields/link.py,sha256=kN_gjRUEEj5cy8K_BwPijYg3TiWhedc24apXYlTbRJs,4172
|
138
139
|
nucliadb/ingest/fields/text.py,sha256=tFvSQJAe0W7ePpp2_WDfLiE2yglR1OTU0Zht9acvOFw,1594
|
139
140
|
nucliadb/ingest/orm/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
140
|
-
nucliadb/ingest/orm/brain.py,sha256=
|
141
|
-
nucliadb/ingest/orm/broker_message.py,sha256=
|
141
|
+
nucliadb/ingest/orm/brain.py,sha256=lvO6bF0usfbZ5T7bDPoVALfocvxTFrCE3YhQrz-d1q8,29831
|
142
|
+
nucliadb/ingest/orm/broker_message.py,sha256=XWaiZgDOz94NPOPT-hqbRr5ZkpVimUw6PjUJNftfoVw,7514
|
142
143
|
nucliadb/ingest/orm/entities.py,sha256=3_n6lKhBy2GsdmNmkh0_mvxP8md20OZsbtTNEmfJ8Hg,14888
|
143
144
|
nucliadb/ingest/orm/exceptions.py,sha256=k4Esv4NtL4TrGTcsQpwrSfDhPQpiYcRbB1SpYmBX5MY,1432
|
144
145
|
nucliadb/ingest/orm/knowledgebox.py,sha256=IGOPvBR1qXqDxE5DeiOdYCLdPgjzOVVpsASJ2zYvWwQ,23651
|
145
146
|
nucliadb/ingest/orm/metrics.py,sha256=OkwMSPKLZcKba0ZTwtTiIxwBgaLMX5ydhGieKvi2y7E,1096
|
146
|
-
nucliadb/ingest/orm/resource.py,sha256=
|
147
|
+
nucliadb/ingest/orm/resource.py,sha256=tukAbD32HrRbVa_Ppo9H2YaYQyq659BzOQ45643sp7E,44964
|
147
148
|
nucliadb/ingest/orm/utils.py,sha256=vCe_9UxHu26JDFGLwQ0wH-XyzJIpQCTK-Ow9dtZR5Vg,2716
|
148
149
|
nucliadb/ingest/orm/processor/__init__.py,sha256=Aqd9wCNTvggkMkCY3WvoI8spdr94Jnqk-0iq9XpLs18,922
|
149
150
|
nucliadb/ingest/orm/processor/auditing.py,sha256=TeYhXGJRyQ7ROytbb2u8R0fIh_FYi3HgTu3S1ribY3U,4623
|
@@ -226,11 +227,11 @@ nucliadb/search/search/fetch.py,sha256=XJHIFnZmXM_8Kb37lb4lg1GYG7cZ1plT-qAIb_Qzi
|
|
226
227
|
nucliadb/search/search/filters.py,sha256=1MkHlJjAQqoRCj7e5cEzK2HvBxGLE17I_omsjiklbtw,6476
|
227
228
|
nucliadb/search/search/find.py,sha256=p7Odx3hjPwTsHEhQrVYsR_ufq0meMmCnQV0YihfOmlg,10237
|
228
229
|
nucliadb/search/search/find_merge.py,sha256=3FnzKFEnVemg6FO_6zveulbAU7klvsiPEBvLrpBBMg8,17450
|
229
|
-
nucliadb/search/search/graph_merge.py,sha256=
|
230
|
+
nucliadb/search/search/graph_merge.py,sha256=OiUNiXOWwrUVKqStuRcoUJwvDbDYamqIgiAy_FwPdMI,3405
|
230
231
|
nucliadb/search/search/graph_strategy.py,sha256=gisL2GpbSIa_SucyOwEt7TWdqURyAQqxvD_-PkXQct8,32339
|
231
232
|
nucliadb/search/search/hydrator.py,sha256=-R37gCrGxkyaiHQalnTWHNG_FCx11Zucd7qA1vQCxuw,6985
|
232
233
|
nucliadb/search/search/ingestion_agents.py,sha256=NeJr4EEX-bvFFMGvXOOwLv8uU7NuQ-ntJnnrhnKfMzY,3174
|
233
|
-
nucliadb/search/search/merge.py,sha256=
|
234
|
+
nucliadb/search/search/merge.py,sha256=aNjghwyQDuoIuddFt37_kHAUv4FDYgGtdP3dM1SBUWs,22966
|
234
235
|
nucliadb/search/search/metrics.py,sha256=GGGtXHLhK79_ESV277xkBVjcaMURXHCxYG0EdGamUd8,2886
|
235
236
|
nucliadb/search/search/paragraphs.py,sha256=pNAEiYqJGGUVcEf7xf-PFMVqz0PX4Qb-WNG-_zPGN2o,7799
|
236
237
|
nucliadb/search/search/pgcatalog.py,sha256=s_J98fsX_RuFXwpejpkGqG-tD9ELuzz4YQ6U3ew5h2g,9313
|
@@ -256,7 +257,7 @@ nucliadb/search/search/query_parser/old_filters.py,sha256=-zbfN-RsXoj_DRjh3Lfp-w
|
|
256
257
|
nucliadb/search/search/query_parser/parsers/__init__.py,sha256=ySCNSdbesLXGZyR88919njulA6UE10_3PhqMG_Yj1o4,1034
|
257
258
|
nucliadb/search/search/query_parser/parsers/catalog.py,sha256=XdBiTweGTQkj8m_V_i2xbwp7P5pPO8K1Tud692XKhMw,7149
|
258
259
|
nucliadb/search/search/query_parser/parsers/find.py,sha256=q3wH_i0DGceeKckYEH3c5MqM5EvRiMCL7r-6nCAId9Q,4666
|
259
|
-
nucliadb/search/search/query_parser/parsers/graph.py,sha256=
|
260
|
+
nucliadb/search/search/query_parser/parsers/graph.py,sha256=fdzKzwnwhSkMXgt8bKXsvBFR8zWjb12lKAgtPzGr37c,6396
|
260
261
|
nucliadb/standalone/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
261
262
|
nucliadb/standalone/api_router.py,sha256=hgq9FXpihzgjHkwcVGfGCSwyXy67fqXTfLFHuINzIi0,5567
|
262
263
|
nucliadb/standalone/app.py,sha256=mAApNK_iVsQgJyd-mtwCeZq5csSimwnXmlQGH9a70pE,5586
|
@@ -352,8 +353,8 @@ nucliadb/writer/tus/local.py,sha256=7jYa_w9b-N90jWgN2sQKkNcomqn6JMVBOVeDOVYJHto,
|
|
352
353
|
nucliadb/writer/tus/s3.py,sha256=vF0NkFTXiXhXq3bCVXXVV-ED38ECVoUeeYViP8uMqcU,8357
|
353
354
|
nucliadb/writer/tus/storage.py,sha256=ToqwjoYnjI4oIcwzkhha_MPxi-k4Jk3Lt55zRwaC1SM,2903
|
354
355
|
nucliadb/writer/tus/utils.py,sha256=MSdVbRsRSZVdkaum69_0wku7X3p5wlZf4nr6E0GMKbw,2556
|
355
|
-
nucliadb-6.3.4.
|
356
|
-
nucliadb-6.3.4.
|
357
|
-
nucliadb-6.3.4.
|
358
|
-
nucliadb-6.3.4.
|
359
|
-
nucliadb-6.3.4.
|
356
|
+
nucliadb-6.3.4.post3694.dist-info/METADATA,sha256=yo17tzuCOWQgea8j1Eqbz0bxeZQ92VwtVowbvZAI7jM,4291
|
357
|
+
nucliadb-6.3.4.post3694.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
|
358
|
+
nucliadb-6.3.4.post3694.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
|
359
|
+
nucliadb-6.3.4.post3694.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
|
360
|
+
nucliadb-6.3.4.post3694.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|