全文检索语法

  • 创建全文索引

创建全文索引使用现有的语法结构,增加全文索引类型 "text",在索引的 key 定义中指定。索引的其它选项对全文索引无效,因此无需指定。以下语句在集合 foo.bar 的 name 及 address 字段上创建复合全文索引:

  1. > db.foo.bar.createIndex('idx', {name:"text", address:"text"})

可指定一个或多个字段,需要注意的是在创建时 text 类型不可与其它任何类型混用。每创建一个全文索引,会在数据节点上对应地创建一个固定集合空间及固定集合(集合与集合空间同名,以 SYS_ 开头,与全文索引的对应关系可通过直连数据节点并使用 listIndexes() 进行查询)。文档在 Elasticsearch 中进行索引时,会使用原始集合中文档的 _id 字段的值生成 Elasticsearch 中文档的 _id,支持的原始文档的 _id 类型包括:

  • 32-bit integer
  • 64-bit integer
  • double
  • decimal
  • string
  • ObjectID
  • boolean
  • date
  • timestamp
  • Object全文索引在使用时存在以下约束:

  • 建议包含全文索引的集合中文档的 _id 值保持唯一,不唯一的情况下,在 Elasticsearch 上对应的文档不全,通过全文检索查询到的结果也会不全。这是由于在 Elasticsearch 的索引中,通过 _id 来唯一标识一个文档,而这个 _id 是通过 SequoiaDB 中文档的 _id 转换而来,对于 Elasticsearch,索引两个 _id 相同的文档,是进行一个 update 操作,先插入的文档会被覆盖。

  • 一个集合上最多创建 1 个全文索引
  • 数据库中最多创建 64 个全文索引
  • 只有字符串或字符串数组类型的字段会被索引,非字符串字段会被忽略
  • 不包含任何全文索引字段的文档将不会被索引,也无法被全文检索语法查询到(包括 Elasticsearch 中的 match_all 查询)
  • _id 字段类型不在受支持列表的文档不会被索引,也无法被全文检索语法查询到(包括 Elasticsearch 中的 match_all 查询)
  • SequoiaDB 记录中的 _id 在转换为 Elasticsearch 中的 _id 时进行了编码,由于 Elasticsearch 限制文档 _id 的最大长度为 512,只有 _id 值长度小于 254 字节的原始记录会被索引到 Elasticsearch 上,长度超过这个值的记录都会被忽略。基于性能方面的考虑,应尽量避免使用太长的 _id
  • 不包含全文检索语法中使用到的任何字段的记录无法被查询到
    • 删除全文索引

删除全文索引使用 dropIndex 语法,指定索引名即可。

  1. > db.foo.bar.dropIndex('idx')

在索引被删除时,其对应的固定集合空间也会一并删除。

  • 全文检索

SequoiaDB 适配的全文检索引擎为 Elasticsearch,通过在 SequoiaDB 的查询语法中包含 Elasticsearch 的搜索条件来进行全文检索。基本语法结构为:

  1. > db.foo.bar.find( { "" : { $Text : <search command> } } )

其中的 search command 即 Elasticsearch 的搜索条件。search command 部分支持 Elasticsearch 的 DSL(Domain Specific Language 特定领域语言)语句。因此,需要使用全文检索功能的用户,需要掌握 Elasticsearch 的 DSL 语言。以下示例程序在集合中查找 name 中包含 "Smith" 的所有记录:

  1. > db.createCS('megacorp').createCL('employee')
  2. localhost:11810.megacorp.employee
  3. Takes 1.246399s.
  4. > db.megacorp.employee.createIndex('idx_1', {first_name:"text", "last_name":"text", "age":"text", "about":"text", "interests": "text"})
  5. Takes 1.182447s.
  6. > db.megacorp.employee.insert({"first_name" : "John","last_name" : "Smith","age" : 25,"about" : "I love to go rock climbing","interests": [ "sports", "music" ]})
  7. Takes 0.009290s.
  8. > db.megacorp.employee.insert({"first_name" : "Jane","last_name" : "Smith","age" : 32,"about" : "I like to collect rock albums","interests": [ "music" ]})
  9. Takes 0.001013s.
  10. > db.megacorp.employee.insert({"first_name" : "Douglas","last_name" : "Fir","age" : 35,"about": "I like to build cabinets","interests": [ "forestry" ]})
  11. Takes 0.001004s.
  12. > db.megacorp.employee.find({"":{"$Text":{"query":{"match":{"about" : "rock climbing"}}}}})
  13. {
  14. "_id": {
  15. "$oid": "5a8f8d9c89000a0906000000"
  16. },
  17. "first_name": "John",
  18. "last_name": "Smith",
  19. "age": 25,
  20. "about": "I love to go rock climbing",
  21. "interests": [
  22. "sports",
  23. "music"
  24. ]
  25. }
  26. {
  27. "_id": {
  28. "$oid": "5a8f8d9f89000a0906000001"
  29. },
  30. "first_name": "Jane",
  31. "last_name": "Smith",
  32. "age": 32,
  33. "about": "I like to collect rock albums",
  34. "interests": [
  35. "music"
  36. ]
  37. }
  38. Return 2 row(s).
  39. Takes 1.181983s.