1

Let's say I have a datomic data that looks like this -

Author (id: 5) {
 name: "Mercy",
 blogs: [1, 2]
}

Blog (id: 1) {
 title: "Hello blog"
}

Blog (id: 2) {
 title: "Hello blog second"
}

I want to find a author by name and all the title of their blogs and count of blogs. So far, I have

[:find ?blogs ?c
 :where
 [?e :name "Mercy"]
 [?e :blogs ?blogs]
 [(count ?blogs) ?c]
]

I was only able to get the total count of blogs. How can I get the title of the blogs using just datalog queries? I also cannot have belongs_to relationship on the blog entity.

Update

'author/blogs' has schema that looks like:

{
 :db/ident :blog
 :db/valueType :db.type/ref
 :db/cardinality :db.cardinality/many    
}
Lordking
  • 1,413
  • 1
  • 13
  • 31

2 Answers2

1

You can retrieve the :title from the entities after pulling all the attributes of the entity:

[:find [(pull ?blogs '[:title]) ...] ?count
 :where
 [?e :name "Mercy"]
 [?e :blogs ?blogs]
 [(count ?blogs) ?count]

Let me know if it works.

user2609980
  • 10,264
  • 15
  • 74
  • 143
  • it didn't work :( . ?blogs is just a vector of refs. i want to use the ids in that vector to fetch the blogs. – Lordking Aug 10 '17 at 14:46
  • @Lordking clear. You need to pull the rest of the attributes. Let me update the answer, so you can check. :) – user2609980 Aug 10 '17 at 16:09
  • doing (pull ?blogs [:title]) seems to work for me (not what i want) but not [(pull ?blogs '[:title]) ...] – Lordking Aug 11 '17 at 16:15
  • @Lordking great. Why isn't it what you want? You retrieve all titles right? Using the Entities API as specified by Nikita above is also a good idea. – user2609980 Aug 12 '17 at 19:26
1

It’s just

[:find ?e (count ?b)
 :where
 [?e :name "Mercy"]
 [?e :blogs ?b]]

It would work even if you remove author’s name, then you’ll get “map” of author → blog count

[:find ?e ?n (count ?b)
 :where
 [?e :name ?n]
 [?e :blogs ?b]]

Don’t forget for these queries to work efficiently :name should be indexed (:db/index true in schema).

But if the question is that simple, I’d recommend to go through entities API really, should be much more efficient:

(-> (d/entity db [:name "Mary"])
    (:blogs)
    (count))

For ref lookup to work ((d/entity db [:name "Mary"])), you’ll need to specify :name as unique attribute in schema

Niki Tonsky
  • 1,327
  • 11
  • 19