Merge pull request #2351 from paperless-ngx/feature-comment-search

Feature: include comments in advanced search
This commit is contained in:
shamoon 2023-01-05 18:48:51 -08:00 committed by GitHub
commit a0eecb83cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 3 deletions

View File

@ -25,7 +25,13 @@
</h5> </h5>
</div> </div>
<p class="card-text"> <p class="card-text">
<span *ngIf="document.__search_hit__" [innerHtml]="document.__search_hit__.highlights"></span> <span *ngIf="document.__search_hit__ && document.__search_hit__.highlights" [innerHtml]="document.__search_hit__.highlights"></span>
<span *ngIf="document.__search_hit__ && document.__search_hit__.comment_highlights">
<svg width="1em" height="1em" fill="currentColor" class="me-2">
<use xlink:href="assets/bootstrap-icons.svg#chat-left-text"/>
</svg>
<span [innerHtml]="document.__search_hit__.comment_highlights"></span>
</span>
<span *ngIf="!document.__search_hit__" class="result-content">{{contentTrimmed}}</span> <span *ngIf="!document.__search_hit__" class="result-content">{{contentTrimmed}}</span>
</p> </p>

View File

@ -10,6 +10,7 @@ export interface SearchHit {
rank?: number rank?: number
highlights?: string highlights?: string
comment_highlights?: string
} }
export interface PaperlessDocument extends ObjectWithId { export interface PaperlessDocument extends ObjectWithId {

View File

@ -5,6 +5,7 @@ from contextlib import contextmanager
from dateutil.parser import isoparse from dateutil.parser import isoparse
from django.conf import settings from django.conf import settings
from documents.models import Comment
from documents.models import Document from documents.models import Document
from whoosh import classify from whoosh import classify
from whoosh import highlight from whoosh import highlight
@ -49,6 +50,7 @@ def get_schema():
path=TEXT(sortable=True), path=TEXT(sortable=True),
path_id=NUMERIC(), path_id=NUMERIC(),
has_path=BOOLEAN(), has_path=BOOLEAN(),
comments=TEXT(),
) )
@ -90,6 +92,7 @@ def open_index_searcher():
def update_document(writer, doc): def update_document(writer, doc):
tags = ",".join([t.name for t in doc.tags.all()]) tags = ",".join([t.name for t in doc.tags.all()])
tags_ids = ",".join([str(t.id) for t in doc.tags.all()]) tags_ids = ",".join([str(t.id) for t in doc.tags.all()])
comments = ",".join([str(c.comment) for c in Comment.objects.filter(document=doc)])
writer.update_document( writer.update_document(
id=doc.pk, id=doc.pk,
title=doc.title, title=doc.title,
@ -110,6 +113,7 @@ def update_document(writer, doc):
path=doc.storage_path.name if doc.storage_path else None, path=doc.storage_path.name if doc.storage_path else None,
path_id=doc.storage_path.id if doc.storage_path else None, path_id=doc.storage_path.id if doc.storage_path else None,
has_path=doc.storage_path is not None, has_path=doc.storage_path is not None,
comments=comments,
) )
@ -255,7 +259,7 @@ class DelayedFullTextQuery(DelayedQuery):
def _get_query(self): def _get_query(self):
q_str = self.query_params["query"] q_str = self.query_params["query"]
qp = MultifieldParser( qp = MultifieldParser(
["content", "title", "correspondent", "tag", "type"], ["content", "title", "correspondent", "tag", "type", "comments"],
self.searcher.ixreader.schema, self.searcher.ixreader.schema,
) )
qp.add_plugin(DateParserPlugin()) qp.add_plugin(DateParserPlugin())

View File

@ -458,10 +458,19 @@ class DocumentViewSet(
class SearchResultSerializer(DocumentSerializer): class SearchResultSerializer(DocumentSerializer):
def to_representation(self, instance): def to_representation(self, instance):
doc = Document.objects.get(id=instance["id"]) doc = Document.objects.get(id=instance["id"])
commentTerm = instance.results.q.subqueries[0]
comments = ",".join(
[
str(c.comment)
for c in Comment.objects.filter(document=instance["id"])
if commentTerm.text in c.comment
],
)
r = super().to_representation(doc) r = super().to_representation(doc)
r["__search_hit__"] = { r["__search_hit__"] = {
"score": instance.score, "score": instance.score,
"highlights": instance.highlights("content", text=doc.content) "highlights": instance.highlights("content", text=doc.content),
"comment_highlights": instance.highlights("content", text=comments)
if doc if doc
else None, else None,
"rank": instance.rank, "rank": instance.rank,