如果字符串有' - '如何进行全文搜索?在例如" 3da549f0-0e88-4297-b6af-5179b74bd929"?

时间:2016-04-20 08:17:42

标签: java arangodb arangojs

当我为该字段建立索引并搜索具有' - '在上面的例子中,Arango将其视为否定运算符,因此不搜索该字符串。搜索包含' - '的这些文件的解决方案是什么?在它?

2 个答案:

答案 0 :(得分:1)

编辑: 我刚看了the source code。它从那里看起来像' - '如果它是字符串中的第一个字符,应该只是一个问题。并且它不是上面给出的示例中的第一个字符,所以我很困惑。

没有任何方法可以逃避' - '字符。另一个想法可能是' - '用' +'。你试过了吗?

collection.fulltext(attribute, "3da549f0+-0e88+-4297+-b6af+-5179b74bd929");

我从阅读the docs中猜到,使用"前缀:"或者"完成:"逃避可能有用。

collection.fulltext(attribute, "complete:3da549f0-0e88-4297-b6af-5179b74bd929");

但显然它没有。

答案 1 :(得分:1)

尝试重现你的所作所为。如果你提供一个更好的可重复的例子(仅限arangosh),你的回答可能更准确:

http+tcp://127.0.0.1:8529@_system> db._create("testIndex")
http+tcp://127.0.0.1:8529@_system> db.testIndex.ensureIndex({type: "fulltext", fields: ["complete:3da549f0-0e88-4297-b6af-5179b74bd929"]})
{ 
  "fields" : [ 
    "complete:3da549f0-0e88-4297-b6af-5179b74bd929" 
  ], 
  "id" : "testIndex/4687162", 
  "minLength" : 2, 
  "sparse" : true, 
  "type" : "fulltext", 
  "unique" : false, 
  "isNewlyCreated" : true, 
  "code" : 201 
}

http+tcp://127.0.0.1:8529@_system> db.testIndex.save({'complete:3da549f0-0e88-4297-b6af-5179b74bd929': "find me"})
{ 
  "_id" : "testIndex/4687201", 
  "_key" : "4687201", 
  "_rev" : "4687201" 
}

http+tcp://127.0.0.1:8529@_system> db._query('FOR doc IN FULLTEXT(testIndex, "complete:3da549f0-0e88-4297-b6af-5179b74bd929", "find") RETURN doc')
[object ArangoQueryCursor, count: 1, hasMore: false]


[ 
  { 
    "_id" : "testIndex/4687201", 
    "_key" : "4687201", 
    "_rev" : "4687201", 
    "complete:3da549f0-0e88-4297-b6af-5179b74bd929" : "find me" 
  } 
]

所以用例看起来不同:

db.test2.save({id: 'complete:3da549f0-0e88-4297-b6af-5179b74bd929'})
db.test2.ensureIndex({type: "fulltext", fields: ["id"]})

db._query('FOR doc IN FULLTEXT(test2, "id", "3da549f0-0e88-4297-b6af-5179b74bd929") RETURN doc')

将返回空结果。

要了解最新情况,需要了解全文索引的工作原理。它将文本分割为word boundaries并将其存储为列表,并在索引中引用该文档。索引全局词表中的一个单词可能会引用多个文档。

查询索引后,将在索引全局词列表中搜索请求的单词,找到的每个单词将包含一个包含单词的文档列表。这些存储桶被组合在一起,并作为要迭代的文档的总列表返回。

了解the tokenizer a little better, I've added a tiny js wrapper that invokes it

让我们看看它对你的字符串做了什么:

SYS_SPLIT_WORDS_ICU("ab cd", 0)
[ 
  "ab", 
  " ", 
  "cd" 
]
SYS_SPLIT_WORDS_ICU("3da549f0-0e88-4297-b6af-5179b74bd929", 0)
[ 
  "3da549f0", 
  "-", 
  "0e88", 
  "-", 
  "4297", 
  "-", 
  "b6af", 
  "-", 
  "5179b74bd929" 
]

所以你看,减去被视为单词边界,你的字符串是分区的。你现在有几个机会来规避这个:

  • 删除插入时的缺点
  • 拆分搜索字符串,并使用散列中最有意义的部分,然后使用FILTER语句作为实际值
  • 根本不使用全文索引,而是跳过列表或哈希索引;它们维护起来更便宜,可以用于FILTER语句