113 lines
3.8 KiB
Python
113 lines
3.8 KiB
Python
from django.conf import settings
|
|
import certifi
|
|
|
|
from pymongo import MongoClient
|
|
|
|
from django.db.models import Case, When, IntegerField
|
|
|
|
from projects.models import Project
|
|
from portfolios.models import Portfolio
|
|
|
|
NOCODETOOL_MODEL_MAP = {
|
|
'project': Project,
|
|
'portfolio': Portfolio,
|
|
}
|
|
|
|
class NocodetoolSearchService:
|
|
@staticmethod
|
|
def search(search_term, object_type, page, page_size):
|
|
client = MongoClient(settings.MONGODB_URI, tlsCAFile=certifi.where())
|
|
db = client[settings.MONGODB_NAME]
|
|
coll = db["code"]
|
|
|
|
filters = []
|
|
if object_type in ("project", "portfolio"):
|
|
filters.append({"term": {"path": "object_type", "query": object_type}})
|
|
|
|
pipeline = [
|
|
{
|
|
"$search": {
|
|
"index": "nocodetool_content_keyword_search_index",
|
|
"compound": {
|
|
"filter": filters,
|
|
"should": [
|
|
{
|
|
"text": {
|
|
"query": search_term,
|
|
"path": "keyword",
|
|
"score": {"boost": {"value": 5}}
|
|
}
|
|
},
|
|
{
|
|
"text": {
|
|
"query": search_term,
|
|
"path": "pages.elements.content",
|
|
"score": {"boost": {"value": 10}}
|
|
}
|
|
},
|
|
{
|
|
"text": {
|
|
"query": search_term,
|
|
"path": "description",
|
|
"score": {"boost": {"value": 7}}
|
|
}
|
|
}
|
|
],
|
|
"minimumShouldMatch": 1
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"$project": {
|
|
"keyword": 1,
|
|
"description": 1,
|
|
"pages.elements.content": 1,
|
|
"object_type": 1,
|
|
"object_id": 1,
|
|
"score": {"$meta": "searchScore"}
|
|
}
|
|
},
|
|
{
|
|
"$facet": {
|
|
"projects": [
|
|
{"$match": {"object_type": "project"}},
|
|
{"$sort": {"score": -1}},
|
|
{"$skip": (page - 1) * page_size},
|
|
{"$limit": page_size}
|
|
],
|
|
"portfolios": [
|
|
{"$match": {"object_type": "portfolio"}},
|
|
{"$sort": {"score": -1}},
|
|
{"$skip": (page - 1) * page_size},
|
|
{"$limit": page_size}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
|
|
agg_result = list(coll.aggregate(pipeline))
|
|
print(agg_result)
|
|
buckets = agg_result[0] if agg_result else {"projects": [], "portfolios": []}
|
|
return buckets
|
|
|
|
def get_ids_from_buckets(buckets: list) -> list:
|
|
return [object["object_id"] for object in buckets]
|
|
|
|
|
|
|
|
class NocodetoolToObjectService:
|
|
def get_objects_by_ids(object_type, objects_ids: list) -> list:
|
|
if not objects_ids:
|
|
return []
|
|
|
|
order = Case(
|
|
*[When(id=pk, then=pos) for pos, pk in enumerate(objects_ids)],
|
|
output_field=IntegerField()
|
|
)
|
|
|
|
object_model = NOCODETOOL_MODEL_MAP.get(object_type)
|
|
if not object_model:
|
|
return []
|
|
|
|
return list(object_model.objects.filter(id__in=objects_ids).order_by(order))
|