我有一个看起来大致相似的模型(在JSON中):
{"gender": "female",
"name": [
{"family": "Smith",
"given": ["Samantha"],
"middle": ["Lee"]]}}
Run Code Online (Sandbox Code Playgroud)
有大约6M的记录具有这样的结构.我需要使用OR子句在人名的所有组件上提供全文搜索.例如,如果用户输入"smith",我需要检查所有给定,中间和姓氏.
在Datomic中,我制作了一个模式:
{:db/ident :model/name
:db/valueType :db.type/ref
:db/isComponent true
:db/cardinality :db.cardinality/many}
{:db/ident :model.name/family
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/fulltext true}
{:db/ident :model.name/given
:db/valueType :db.type/string
:db/cardinality :db.cardinality/many
:db/fulltext true}
{:db/ident :model.name/middle
:db/valueType :db.type/string
:db/cardinality :db.cardinality/many
:db/fulltext true}
Run Code Online (Sandbox Code Playgroud)
注意,我提供了这些属性的全文索引.现在,当我通过单个属性查询时family,性能很好(大约100ms):
(def query-all
'[:find [(rand 100 ?model) ...]
:in $ ?search
:where
[(fulltext $ :model.name/family ?search) [[?name _ _ _]]]
[?model :model/name ?name]])
Run Code Online (Sandbox Code Playgroud)
但是当我使用OR子句添加其他条件时,性能会急剧下降(20秒):
(def query-all
'[:find [(rand 100 ?model) ...]
:in $ ?search
:where
(or
[(fulltext $ :model.name/family ?search) [[?name _ _ _]]]
[(fulltext $ :model.name/given ?search) [[?name _ _ _]]]
[(fulltext $ :model.name/middle ?search) [[?name _ _ _]]])
[?model :model/name ?name]])
Run Code Online (Sandbox Code Playgroud)
我的问题是,我怎么能改善它?
如果我们更进一步,那么也不仅仅是通过名称,而是通过地址的组件找到它也会很棒.理想情况下,会有以下查询(也很慢):
(def query-all
'[:find [(rand 100 ?model) ...]
:in $ ?search
:where
(or
(and
[(fulltext $ :model.name/given ?search) [[?e _ _ _]]]
[?p :model/name ?e])
(and
[(fulltext $ :model.name/middle ?search) [[?e _ _ _]]]
[?p :model/name ?e])
(and
[(fulltext $ :model.name/prefix ?search) [[?e _ _ _]]]
[?p :model/name ?e])
(and
[(fulltext $ :model.name/suffix ?search) [[?e _ _ _]]]
[?p :model/name ?e])
(and
[(fulltext $ :model.name/family ?search) [[?e _ _ _]]]
[?p :model/name ?e])
(and
[(fulltext $ :model.address/city ?search) [[?e _ _ _]]]
[?p :model/address ?e])
(and
[(fulltext $ :model.address/state ?search) [[?e _ _ _]]]
[?p :model/address ?e]))])
Run Code Online (Sandbox Code Playgroud)
我该如何实现?
小智 4
我们处于同样的情况,最终使用了一种解决方法:
我们创建了一个连接所有其他字符串属性的属性。当然,使用该属性的全文进行查询。
| 归档时间: |
|
| 查看次数: |
486 次 |
| 最近记录: |