-
Notifications
You must be signed in to change notification settings - Fork 0
/
db_service.py
145 lines (125 loc) · 5.44 KB
/
db_service.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import os
from pymongo import MongoClient
from pymongo.server_api import ServerApi
from dotenv import load_dotenv
import logging
import certifi
from http.cookiejar import Cookie
from icloudpy import ICloudPyService
import time
# Настройка логирования
# logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO) # Устанавливаем уровень логирования на INFO
load_dotenv()
ICLOUD_USERNAME = os.getenv('ICLOUD_USERNAME')
ICLOUD_PASSWORD = os.getenv('ICLOUD_PASSWORD')
class DatabaseService:
def __init__(self):
self.client = None
self.db = None
self.notes_collection = None
self.initialize_db()
def initialize_db(self):
try:
uri = os.getenv('MONGODB_URI')
if not uri:
raise ValueError("MONGODB_URI not found in environment variables")
# self.client = MongoClient(uri, server_api=ServerApi('1'))
self.client = MongoClient(uri, server_api=ServerApi('1'), tlsCAFile=certifi.where())
self.db = self.client['apple-notes']
self.notes_collection = self.db['notes']
self.sessions_collection = self.db['sessions']
# Проверка подключения
self.client.admin.command('ping')
logger.info("Successfully connected to MongoDB")
except Exception as e:
logger.error(f"An error occurred while connecting to MongoDB: {e}")
raise
def insert_or_update(self, note_data):
try:
# Проверяем наличие обязательных полей
required_fields = ['title', 'text', 'record_id', 'created_date', 'last_edited_date',
'folder_id', 'folder_name', 'owner_id', 'embeddings']
for field in required_fields:
if field not in note_data:
raise ValueError(f"Missing required field: {field}")
# Подготовка данных для вставки/обновления
query = {"record_id": note_data["record_id"]}
update = {"$set": note_data}
# Вставка или обновление документа
result = self.notes_collection.update_one(query, update, upsert=True)
if result.upserted_id:
logger.info(f"Inserted new note with ID: {result.upserted_id}")
else:
logger.info(f"Updated existing note with ID: {note_data['record_id']}")
return result.upserted_id or note_data['record_id']
except Exception as e:
logger.error(f"An error occurred while inserting/updating note: {e}")
raise
def get_last_edited_dates(self):
result = {}
for note in self.notes_collection.find({}, {'record_id': 1, 'last_edited_date': 1}):
result[note['record_id']] = note['last_edited_date']
return result
def close_connection(self):
if self.client:
self.client.close()
logger.info("Closed connection to MongoDB")
# Метод для векторного поиска
def vector_search_notes(self, query_vector, owner_id, index_name="content_vector_index", limit=5, num_candidates=100):
try:
pipeline = [
{
'$vectorSearch': {
'index': index_name,
'path': 'embeddings',
'queryVector': query_vector,
'numCandidates': num_candidates,
'limit': limit,
'filter': {
'owner_id': owner_id
}
}
},
{
'$addFields': {
'score': {'$meta': 'vectorSearchScore'}
}
},
{
'$project': {
'_id': 0, # Исключаем поле _id, если оно вам не нужно
'score': 1, # Явно включаем поле score
# Добавляем все остальные поля
'record_id': 1,
'owner_id': 1,
'created_date': 1,
'last_edited_date': 1,
'folder_name': 1,
'title': 1,
'text': 1
}
}
]
results = list(self.notes_collection.aggregate(pipeline))
return results
except Exception as e:
logger.error(f"Vector search failed: {e}")
return None
# Пример использования
if __name__ == "__main__":
db_service = DatabaseService()
test_note = {
'title': 'Test Note',
'text': 'This is a test note',
'record_id': 'test123',
'created_date': 1234567890,
'last_edited_date': 1234567891,
'folder_id': 'folder123',
'folder_name': 'Test Folder',
'owner_id': 'owner123',
'embeddings': [0.1, 0.2, 0.3] * 1024 # Пример эмбеддинга размерностью 3072
}
db_service.insert_or_update(test_note)
db_service.close_connection()