MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Przeanalizuj zapytanie sql za pomocą antlr parsetree do dokumentu mongo bson w Javie

W jednej z moich poprzednich prac zrobiłem coś podobnego:otrzymałem zapytanie (nie sql, ale całkiem podobne) i przetłumaczyłem je na zapytanie mongo za pomocą antlr.

Nie mam kodu do udostępnienia, ale mogę podzielić się swoimi przemyśleniami:

  1. Mongo nie jest zgodny z SQL, więc nie możesz po prostu wziąć gramatyki sql. A co z JOIN i całą algebrą relacyjną? A co z agregacjami, które są dość trudne w mongo z ich strukturą agregacji? W przeciwnym kierunku, jak generujesz SQL, który jest tłumaczony na klauzulę "exists" w mongo. Jest wiele takich rzeczy, niektóre są małe, inne ogromne, ale w końcu musisz mówić o jakimś podzbiorze sql, o jakimś DSL, który może być używany jako język zapytań i wygląda "jak" sql, ponieważ ludzie są przyzwyczajeni do SQL.

  2. Mając to na uwadze, powinieneś stworzyć własną gramatykę, a Antlr wygeneruje dla Ciebie leksykę/parser. Otrzymasz również za pewnik kontrolę składni zapytania w Runtime. Antlr nie będzie w stanie przeanalizować zapytania, jeśli nie jest ono w prawidłowym formacie, oczywiście jakaś reguła gramatyczna zawiedzie. To kolejny powód, aby nie brać SQL „tak jak jest”.

  3. Do tej pory tak dobrze, że stworzyłeś własnego słuchacza / gościa. W moim przypadku zdecydowałem się na utworzenie reprezentacji obiektu zapytania ze stanem wewnętrznym i wszystkim. Więc zapytanie

Select id,name 
from employee 
where age > 30 
 and department = 'IT' 
limit 200

Został przetłumaczony na obiekty typu:


class Query {
   private SelectClause select;
   private FromClause  from;
   private WhereClause where;
   private Limit        limit;
}

class SelectClause {
   private List<String> fields;
}
...
class WhereClause {
   Condition root;
}

interface Condition {
...
}

class AndCondition implements Condition { // the same for Not, Or

}

W przypadku tego konkretnego zapytania wygląda to mniej więcej tak:

Query q = new Query(new SelectClause(["id", "name"]), new FromClause("employee"), new WhereClause(new AndCondition(new SimpleLeafCondition("age", Operators.GT, 30), new  SimpleLeafCondition("department", Operators.EQ, "IT" )), new Limit(30));

Następnie możliwe jest dokonanie pewnych optymalizacji w zapytaniu (takich jak osadzanie klauzul where, jeśli potrzebujesz, lub na przykład manipulowanie częścią „For”, jeśli pracujesz w środowisku wielu dzierżawców i masz różne kolekcje dla różnych dzierżawców).

Przecież można przejść do wzorca projektowego "interpreter" i rekurencyjnie parsować obiekty zapytania i "przetłumaczyć" je na poprawne zapytanie mongo.Pamiętam, że ten krok zajął mi około 1 dnia (było to 7 lat temu z mongo 2 I zgadnij, ale jednak), biorąc pod uwagę poprawną strukturę obiektów reprezentujących zapytanie, nie powinno to być tak skomplikowane. Wspominam o tym, ponieważ wygląda na to, że jest to twój główny problem w pytaniu.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Wybierz długość ciągu w mongodb

  2. Maskowanie danych osobowych w MongoDB i innych bazach danych NoSQL za pośrednictwem…

  3. Tablica wyszukiwania MongoDB obiektów według pola (warunki łączenia i nieskorelowane podzapytania)

  4. Mongoimport do scalania/upsert pól

  5. Filtr wyszukiwania tekstu MongoDB według wielu pól