我有这样的文件:
{
"title": "Hello, World!",
"segments": [
{
"text": "waive such protections",
"start": 0,
"end": 7040
},
{
"text": "in all contexts",
"start": 7040,
"end": 8500
}
]
}
这个例子代表了一个完整句子的结尾:我遇到的问题是,我可以搜索“放弃这种保护”或“在所有上下文中”,但我不能搜索“在所有上下文中放弃这种保护“。
是否有一种方法可以进行短语搜索,并允许短语搜索跨越segments
数组中的多个相邻条目?
**或者,有没有更好的方法可以构建我的文档?我的目标是能够搜索短语,并返回在成绩单中找到该短语的时间戳(这些文档是从vtt文件生成的,但我可以将它们更改为任何我需要的形状)。
现在我正在对查询的所有连续子集进行多个短语搜索。本质上,bool
查询将minimum_should_match
设置为1
,should
设置为短语,搜索waive
,waive such
,waive such protections
,waive such protections in
等。“在所有情况下放弃这种保护”的查询实际上变成了35个查询。这是可行的,但非常缓慢。
1条答案
按热度按时间wswtfjt71#
有没有一种方法可以进行短语搜索,并允许短语搜索跨越
segments
数组中的多个相邻条目?不幸的是,首先Elasticsearch将这些arrays(除非它们是nested)转换为单个文档,然后转换为唯一的单词列表。在这一点上,所有关于相邻字段的信息都丢失了。Elasticsearch documentation更详细:
当一个文档被存储时,它被索引并在near real-time中完全搜索-在1秒内。Elasticsearch使用一种称为反向索引的数据结构,它支持非常快速的全文搜索。倒排索引列出任何文档中出现的每个唯一单词,并标识每个单词出现的所有文档。
正如您所指出的,您可以尝试慢慢地构建一系列查询,这些查询可以找到可能发生拆分的所有可能方式。我建议使用Regexp query至少确保字段中的单词位于开头或结尾,但不支持锚运算符:
Lucene的正则表达式引擎不支持锚操作符,例如
^
(行首)或$
(行尾)。选项一
一个可以改进的想法是简单地添加一个连接相邻
text
字段的字段:然后,您可以执行一个简单的match phrase query,并删除对这35个查询的需要。
这确实会增加索引的大小,并且匹配短语的最大长度在创建索引时设置。
另一件需要注意的事情是,即使匹配了一个数组项,Elasticsearch仍然会返回整个数组。这可以快速增加HTTP响应的大小。为了解决这个问题,可以考虑使用nested arrays,它将数组的每个元素拆分为单独的文档。
然后可以使用inner hits检索这些文档:
然后,您将需要在客户端删除原始
text
字段未以搜索短语的开头结束的任何结果。选项二
但是,对于更复杂或更长的
match_phrase
查询,前面的选项不能很好地扩展,特别是如果您希望允许用户使用simple query string query创建自己的搜索词。为了解决这个问题,你需要将所有的文本数据连接到一个文档中的一个字段中,并直接在每个单词旁边编码时间戳,然后通过pattern replace character filter删除,以便在搜索时忽略数据。
然后,您将需要依靠内置的荧光笔来提取文本的相关部分。
然后,需要在客户端处理命中,以提取时间戳数据:
如果你不担心空间,你也可以包括结束时间戳(例如,waive[0-7040])并调整
char_filter
中的正则表达式希望有帮助