使用MongoDB检查字段是否为更长字符串的子字符串

时间:2018-08-31 13:26:38

标签: node.js mongodb mongoose

我正在尝试寻找一种基于字段是否为给定字符串的子字符串返回文档的方法。

我得到的原型工作基本上是从集合中获取所有内容,然后在代码中执行所需的逻辑。在代码中,可以通过遍历每个文档然后返回基于search.includes(field)的文档来找到所需的内容。显然,这不是理想的解决方案,因为获取集合中的每个文档都是一项昂贵的操作,无法很好地扩展。

我接下来要做的是使用MongoDB索引查看文本搜索。这种方法可以工作,但是即使该字段不是搜索的完整子字符串,它也会返回文档。

有什么方法可以构造一个查询来检查文档中的字段是否是给定字符串的确切子字符串?

作为一个例子,这里的三个文档与我的收藏中的文档相似:

{
    "_id": ObjectId("5b893f36e7e6ab1a88f87b39"),
    "trigger": "hello",
    "response": "World"
}

{
    "_id": ObjectId("5b6ca6169cc009573bbc3571"),
    "trigger": "stackoverflow",
    "response": "Is awesome!"
}

{
    "_id": ObjectId("5b6ca6169cc009573bbc3571"),
    "trigger": "foo bar",
    "response": "barfoo"
}

在某些情况下,我期望输出:

搜索字符串stackstackexchange不应返回任何文档,因为没有触发器字段是这些文档的完美子字符串。

字符串hello stackexchange应该只为您提供第一个文档,因为触发字段是搜索字符串的子字符串。

字符串hello stackoverflow将使您同时获得两个文档,因为它们都有一个触发字段,该字段是搜索字符串的子字符串。

编辑:查询还必须处理触发器字段可能包含空格的事实。因此,字符串foo bar foobar应该与最后一个文档匹配,而字符串foo应该与最后一个文档不匹配。

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

经过反复尝试,我找到了实现自己想要的方法。通过在$indexOfBytes中使用$gt,我可以通过查看$indexOfBytes的结果是否大于-1来检查触发器是否在搜索字符串中作为子字符串存在。这是我最后的猫鼬查询:

Collection.find({
    $expr: {
        $gt: [
            {
                $indexOfBytes: [
                    search,
                    "$trigger"
                ]
            },
            -1
        ]
    }
});