Противоречивый результат запроса

#clojure #datomic

#clojure #datomic

Вопрос:

Это вопрос, касающийся datomic on-prem, версии 1.0.6202

Когда я делаю это:

 (d/q '[:find ?LDCustomer-influencer :in $ [?user ...] 
       :where [?LDCustomer-influencer :LDCustomer/baseUser ?LDUser-influencer]
              [?LDCustomer-influencer :LDCustomer/isInfluencer ?val]
              [(= ?val true)]]
     (d/db db/conn) #{17592186248068})
 

Я получаю:

 #{}
 

Когда я делаю это:

 (d/q '[:find ?LDCustomer-influencer :in $ [?user ...]
       :where [?LDCustomer-influencer :LDCustomer/baseUser ?LDUser-influencer]
              [?LDCustomer-influencer :LDCustomer/isInfluencer true]]
     (d/db db/conn) #{17592186248068})
 

Я получаю:

 #{[17592186093717] [17592186246464] [17592186248205] [17592186233070]}
 

(который является правильным результатом)

Почему здесь не работает оператор =?

Ответ №1:

Я понятия не имею о datomic, и я не гуру Java, но подумайте об этом

 user=> (= true [1]) 
false
user=> (= true 1)
false


(clojure.repl/source clojure.core/=) 
; uses `clojure.lang.Util/equiv under the hood
; https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L24

static public boolean equiv(Object k1, Object k2){
    if(k1 == k2)       // !! this will be false
        return true;
    if(k1 != null)     // !! neither of these will succeed
        {
        if(k1 instanceof Number amp;amp; k2 instanceof Number)
            return Numbers.equal((Number)k1, (Number)k2);
        else if(k1 instanceof IPersistentCollection || k2 instanceof IPersistentCollection)
            return pcequiv(k1,k2);
        return k1.equals(k2);
        }
    return false;      // !! you end up with false
}
 

который, я думаю, в конце концов сводится к следующему java

 (Object) Integer.valueOf(1) == (Object) Boolean.valueOf(true)
 

что является ложным

Ответ №2:

Вы должны сделать постоянную привязку как «основную». В datomic это похоже [(ground true) ?val] . Однако, если вы оставите константу в кортежах (как во втором случае), datomic по умолчанию примет ее как «обоснованную».