You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Datahike多字段字符串查询无结果问题求助

我来帮你搞定这个Datahike多字段搜索的问题!你的代码里有两个关键问题导致返回结果不符合预期,调整后就能得到想要的结果:

问题分析

  1. 规则中的函数调用格式错误:Datahike的规则定义里,函数调用必须用方括号[]包裹,你原来写的(?fn ?name ?str)是无效写法,规则无法正确执行字符串匹配逻辑。
  2. 查询中冗余的条件:原查询里的[?e :card/name ?name]是多余的,它不仅没有必要,还会干扰匹配逻辑——虽然测试数据里所有实体都有:card/name字段,但这行条件会强制查询先过滤出所有带name的实体再匹配,而我们需要的是实体任意一个字段(name或text)匹配即可。

修正后的代码(使用规则版本)

(ns my.ns 
  (:require [clojure.string :as st] 
            [datahike.api :as dh]))

(def card-db 
  [[1 :card/name "CardA"] 
   [1 :card/text "Text of CardA mentioning CardB"] 
   [2 :card/name "CardB"] 
   [2 :card/text "A mystery"]])

;; 修正规则中的函数调用,加上方括号
(def rules 
  '[ [(matches-name ?ent ?fn ?str) 
      [?ent :card/name ?name] 
      [(?fn ?name ?str)]]
     [(matches-text ?ent ?fn ?str) 
      [?ent :card/text ?text] 
      [(?fn ?text ?str)]] ])

(defn my-search [db search-strs]
  (dh/q '[:find ?e
          :in $ % ?fn [?str ...]
          :where (or (matches-name ?e ?fn ?str)
                     (matches-text ?e ?fn ?str))]
        db rules st/includes? search-strs))

;; 现在执行测试,会返回2,符合预期
(count (my-search card-db ["CardB"]))

更简洁的无规则版本

如果你不需要用规则,直接在查询里写逻辑会更直观:

(defn my-search-no-rules [db search-strs]
  (dh/q '[:find ?e
          :in $ ?fn [?str ...]
          :where (or (and [?e :card/name ?name] [(?fn ?name ?str)])
                     (and [?e :card/text ?text] [(?fn ?text ?str)]))]
        db st/includes? search-strs))

;; 同样返回预期的2
(count (my-search-no-rules card-db ["CardB"]))

为什么这样修改有效

  • 规则里的函数调用加上方括号后,Datahike能正确识别并执行st/includes?的子串匹配逻辑;
  • 去掉冗余的[?e :card/name ?name]后,查询会检查每个实体的name或text字段是否包含任意一个搜索字符串,这样CardA(text含"CardB")和CardB(name含"CardB")都会被匹配到,最终返回2个结果。

内容的提问来源于stack exchange,提问作者tidecrudra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:52:11