Могу ли я передать вектор в качестве аргумента в двухатомный запрос?
Если бы у меня была схема (в псевдокоде)
{:collection/name
:type "string"},
{:photo/collection
:type ref}
И у меня был вектор из 3 коллекций, из которых я хотел увидеть все фотографии.
Могу ли я сделать что-то вроде ниже? (покажи мне все фотографии из коллекции A, B или C
:find [?p]
:where [?p :photo/collection [17592186045568 17592186045597 17592186045654]]
Я получаю следующую ошибку, когда я пытаюсь что-то вроде этого..
IllegalArgumentExceptionInfo :db.error/invalid-lookup-ref Invalid list form: [[17592186045568 17592186045597 17592186045654]] datomic.error/arg (error.clj:55)
Если я не могу так поступить, могу ли я пойти другим путем?
Обновить:
Я вижу, что в учебнике есть способ передать вектор с помощью... (кстати, есть имя для этого вида запроса?), И я попытался
{:query {:find [?p ?coll], :where [[?p :photo/collection ?coll]], :in [$ [?coll ...]]}
С [17592186045568 17592186045597 17592186045654] в качестве входа, но я все еще получаю ту же ошибку. Кажется, мой синтаксис правильный, потому что я попробовал это с другим атрибутом (не с ссылкой), и он работал нормально. Я просто застрял на рефс. Должна быть лучшая практика для этого?
1 ответ
Вы сделали бы это, используя привязку коллекции. Здесь есть несколько простых иллюстраций этого.
В Learn Datalog Today есть раздел реструктуризации коллекций ! (и проблема 1 использует это, если вы хотите проверить правильность синтаксиса вашего решения).
Подобный подход к вашей проблеме может выглядеть так:
(d/q '[:find ?pid ?collection
:in $ [?collection ...]
:where [?p :photo/collections ?collection]
[?p :photo/id ?pid]]
(d/db conn)
["A" "B" "C"])
Результаты будут примерно такими (если предположить простые целочисленные идентификаторы фотографий - я не уверен, как вы на самом деле идентифицируете фотографии):
[1 "A"]
[2 "A"]
[3 "B"]
Если вам нужны только идентификаторы сущностей, вы можете использовать более простой запрос:
[:find ?p
:in $ [?collection ...]
:where
[?p :photo/collection ?collection]]