watchdogpolska / small_eod

System służący do usprawnienia obiegu dokumentów Stowarzyszenia na potrzeby prowadzonych litygacji Stowarzyszenia
http://small-eod.vercel.app
MIT License
56 stars 43 forks source link

opracowanie parsera zapytań dla Collection #103

Open ad-m opened 4 years ago

ad-m commented 4 years ago

W Collection mamy pole query, które ma zapytanie w postaci tekstowej, które służy do filtrowania spraw w sposób dynamiczny. Ma to na celu sprawienie, abyśmy sformułować wyszukiwanie podobnie do tego co ma GitHub ( https://github.com/issues?q=is%3Aopen+is%3Aissue+author%3Aad-m+archived%3Afalse+label%3Av2 ) i udostępniać sprawy obecne i przyszłe spełniające kryteria wyszukiwania. Z perspektywy deweloperom umożliwi to pobranie spraw należących do kolekcji w sposób podobny do:

Case.objects.filter(parse_query(collection.query))).all()

@mik-laj rekomendował Lark / pyparsing (prostszy) w celu parsowania. Funkcja parse_query musi zwracać obiekty django.db.models.Q ( https://docs.djangoproject.com/en/3.0/topics/db/queries/#complex-lookups-with-q-objects ).

bukowa commented 4 years ago

W jednym ze swoich projektów używałem czegoś takiego, można by to troche zmodyfikować aby zwracać django.db.models.Q ?

class FilterMixin:

    filter_model = None
    filter_params = {}

    def get_filter_params(self):
        filter_params = {}
        for k, v in self.filter_params.items():
            param = self.request.GET.get(k)
            if param:
                filter_params[v] = param
        return filter_params

    def get_queryset(self):
        filter_params = self.get_filter_params()
        return self.filter_model.objects.filter(**filter_params)

class CollectionViewSet(FilterMixin, ModelViewSet):
    serializer_class = CollectionSerializer

    filter_model = Collection
    filter_params = {
        'name': 'name__iexact',
    }

Jest też https://github.com/carltongibson/django-filter

ad-m commented 4 years ago

Znam django-filter. W jaki sposób wówczas przechowywalibyśmy to w bazie danych? Zastanawiałem się (zob. bebfd619236f692f84e67b9f8e6c1c02c70cac4b ) nad obiektem, ale stwierdziłem, że tekst długoterminowo jest lepszym rozwiązaniem, chociaż wymaga pewnego nakładu pracy, bo pozwoli zbudować bardziej dogodne zapytania z AND i OR, ale możemy zacząć od czegoś prostszego.

ad-m commented 4 years ago

Niby można trzymać querystring, ale czy to jest czyste rozwiązanie i odpowiednie długoterminowo? Jeżeli nie będziemy wspierać AND i OR to nie potrzebujemy models.Q.

ad-m commented 4 years ago

Przeglądając materiały na temat Poradni z @AgnieszkaZdanowicz dostrzegłem https://github.com/ivelum/djangoql , które wydaje się dość ciekawe. Biblioteka utrzymywana przez lata ( https://pypi.org/project/djangoql/#history ).

Niepokoi mnie trochę uwiązanie do struktury modelu Django, ale jednocześnie doceniam duży zakres funkcjonalności.

ad-m commented 4 years ago

Powszechna jest składnia Lucene, którą wykorzystuje Elasticsearch. Parser dla niej jest dostępny na https://github.com/pyparsing/pyparsing/blob/master/examples/lucene_grammar.py . Zatem różne podejścia do parsowania mamy. Teraz trzeba by dokładnie zastanowić się jak takie zapytania mają wyglądać i jak mają się przełożyć na SQL.

ad-m commented 4 years ago

Na Slacku zwrócono się do @AgnieszkaZdanowicz z zapytanie:

Czy sądzisz, że będzie Ci wygodni wyszukiwać sprawy poprzez budowanie zapytań podobnie jak jest to dostępne w GitHub? W GitHub jest pole tekstowe, które zawiera specyficzny język zapytań. Dla ułatwienia jego użycia można wybrać opcje filtrowania, co tylko modyfikuje zapytanie. Dzięki temu istnieje zawsze jedna wartość, którą można zapisać, aby zapisać wyniki wyszukiwania jako "Ulubione wyszukiwania", albo - co ważniejsze – kolekcje. Chce się upewnić co sądzisz o pomyśle. image

@AgnieszkaZdanowicz wskazała:

wydaje mi się to wygodne

Co skłania do tego, aby faktycznie to zapytanie przechowywać w postaci tekstowej. Podsuwa nam także propozycje UI. Jak pokazuje GitHub autocomplete to nie jest jedyna droga budowy takich zapytań, bo można po prostu mieć kontroli UI, które modyfikują odpowiednio zapytanie.

ad-m commented 4 years ago

Na ekranie powiadomień GitHub podszedł do problemu w inny sposób: https://github.com/notifications/beta Innowacyjnie i ciekawe.

ad-m commented 4 years ago

Zawsze można to skomplikować, ale poszukuje minimalnego zbioru, który będzie użyteczny.

Myślę zatem, że potrzebujemy następujących elementów w składni:

Teraz pomyślę jak zbudować to wspierający parser.