Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't query entity using :db/id attribute #46

Closed
nahuel opened this issue Jan 3, 2015 · 2 comments
Closed

Can't query entity using :db/id attribute #46

nahuel opened this issue Jan 3, 2015 · 2 comments

Comments

@nahuel
Copy link

nahuel commented Jan 3, 2015

Example:

(let [db                (d/create-conn {})
      {:keys [tempids]} (d/transact! db [{:db/id -1
                                          :name "Mazinger"}])
      new-id            (get tempids -1)]
  (println :entity  (-> @db (d/entity new-id) d/touch))
  (println :by-id   (d/q `[:find ?e
                           :where [?e :db/id ~new-id]]   @db))
  (println :by-name (d/q `[:find ?e
                           :where [?e :name "Mazinger"]] @db)))

;; Output:
:entity {:name Mazinger, :db/id 1}
:by-id #{}  ;; <-- why?
:by-name #{[1]}

Entity is not returned when querying using :db/id. Is this a limitation by design or a bug?

@tonsky
Copy link
Owner

tonsky commented Jan 3, 2015

@nahuel,

:db/id is not a real attribute. It is used to create “map” forms of an entity at insert stage. When you write

(d/transact! db [{:db/id -1 :name "Mazinger"}]

it means, essentially, this: take all key-value pairs from this map, convert them to [:db/add eid attr value] form where attr=key from map, value=value from map, and eid (entity id) is a special key :db/id from map. It’s just a convention. Results from entity calls support this convention too, as they have to represent datoms as maps.

But inside DataScript everything is stored as flat datoms of form [e a v], no maps. If your entity has 10 attributes, there’ll be 10 distinct datoms. Maps are just a convenient view of these internals.

Queries are written in pattern-match style over actual flat datoms, so you cannot use :db/id as it is not an actual datom attribute. When matching over entity id, just use first position, not last one:

(d/q `[:find ?name
       :where [~new-id :name ?name]] @db)

BTW it’s not recommended to use actual values inside query. For parametrized queries, use addtional :in agruments:

(d/q '[:find ?name
       :in $ ?e
       :where [?e :name ?name]] @db new-id)

@tonsky tonsky closed this as completed Jan 3, 2015
@nahuel
Copy link
Author

nahuel commented Jan 3, 2015

Now it's crystal clear, many thanks for the detailed response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants