LINUX.ORG.RU

Не возвращается список коллекций

 , , ,


0

3

Комрады, вопрос по Racket. Использую Rackte + db/mongodb. Получаю коннект к Mongo: (mongo (create-mongo #:host host #:port port)), потом собственно саму БД (database (make-mongo-db mongo db-name)). После этого пытаюсь пользовать (mongo-db-collections db), т.е. делаю (mongo-db-collections database), но получаю как итог - пустой список. Коллекции в БД есть (3 штуки). Цель получить именно имена коллекций в данной БД. В чем может быть проблема?

Заранее всем спасибо за разъяснение.

Технически, запрос списка коллекций выглядит как чтение коллекции с именем «{имя базы}.system.namespaces».

В коде так

(define (mongo-db-collections db)
  (define name (mongo-db-name db))
  (define ans (mongo-find (mongo-db-mongo db) (format "~a.system.namespaces" name) empty))
  (define name-rx (regexp (format "^~a\\.(.+)$" (regexp-quote name))))
  (for/fold ([l empty])
    ([c ans])
    (define n (hash-ref c 'name))
    (match (regexp-match name-rx n)
      [(list _ name)
       (if (regexp-match #rx"\\$" name)
           l
           (list* name l))]
      [#f l])))

Может коллекции как-то созданы без регистрации в ней?

monk ★★★★★ ()
Ответ на: комментарий от monk

Да, уже смотрел. Саму коллекцию создаю через mongo-db-drop-collection!. Первым аргументом я кидаю базу (она получается точно, проверял), а вторым название коллекции (к примеру, points). Как понимаю, то регистрация в system должна проводиться сама по данному методы. Названный метод создания коллекций использую для того, чтобы можно было плодить caped-коллекции (задаётся настройками).

По сути у меня задача - плодить БД и внутренние для неё коллекции по настройкам. Естественно, имена коллекций не должны повторяться или создаваться пытаться повторно. Как обойти это поведение я нашел - использую mongo-db-valid-collection? для проверки есть такая коллекция или нет. Но всё же хотелось бы получить список текущих созданных коллекций в базе и в нём проверку делать (там тоже есть нюанс при создании, где имя не полностью идентично но фактически занято - это желательно реализовать).

silver-bullet-bfg ★★ ()
Последнее исправление: silver-bullet-bfg (всего исправлений: 1)
Ответ на: комментарий от monk

Проверил. Созданная коллекция по QuickStart (https://docs.racket-lang.org/mongodb/Quickstart.html) тоже не регистрируется. И возвращается пустой список для БД созданной по нему же.

Что-то тут я не понимаю… Я сделал:

(define m (create-mongo))
(define d (make-mongo-db m "awesome-dot-com"))
(current-mongo-db d)
(mongo-db-collections db) 

Итог - пустой список.

З.Ы.: Записи в коллекции есть

silver-bullet-bfg ★★ ()
Последнее исправление: silver-bullet-bfg (всего исправлений: 2)

Судя по https://docs.mongodb.com/manual/reference/system-collections/, читать напрямую <database>.system.namespaces – плохая идея.

Судя по https://docs.mongodb.com/manual/reference/command/listCollections/ , надо делать что-то вроде

(mongo-db-execute-command! db '((listCollections . 1)))
monk ★★★★★ ()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk

Спасибо за наводку, в итоге вот такой код помог:

(define get/collections<-execute
  (λ (d f n a)
    (let ([collections (mongo-db-execute-command! d
                                                  (list
                                                   (cons 'listCollections 1)
                                                   (cons 'filter f)
                                                   (cons 'nameOnly n)
                                                   (cons 'authorizedCollections a)))])
      (cond
        [(empty? collections) '()]
        [else (let([cursor (hash-ref collections 'cursor)])
                (let ([firstBatch (hash-ref cursor 'firstBatch)])
                  (for/list ([c (in-vector firstBatch)])
                    (let ([colname (hash-ref c 'name)])
                      (cond
                        [(symbol? colname) (symbol->string colname)]
                        [else colname])))))]))))

Связано с изменением API у MongoDB (теперь listCollections всегда возвращает пустой список). Надо будет поправить в либе да зареквестировать…

silver-bullet-bfg ★★ ()