【问题标题】:mongodb query to exclude only from text indexmongodb 查询仅从文本索引中排除
【发布时间】:2019-08-16 16:23:26
【问题描述】:

我在一个数组字段上有一个文本索引,这是该字段的样子:

{"client":["Aaaa","Bbbb"]},
{"client":["Ccc","Dddd"]},
{"client":["Ccc","Dddd"]},
{"client":["Aaaa","Bbbb"]},
{"client":["Ccc","Dddd"]},
{"client":["Aaaa","Bbbb"]},
{"client":["Ccc","Dddd"]},

并且我需要通过搜索我想要排除的值而不是添加我想要包含的值来获取所有没有 Dddd 的记录 Aaaa-Bbbb

我在这里读到,mongoDB Docs: $text,我可以通过在要排除的单词前添加破折号来排除某些结果,但我不知道如何仅排除。

db.clients.find({$text:{$search: 'Aaaa -Dddd'}})

工作,但我需要做类似的事情:

db.clients.find({$text:{$search: '-Dddd'}})

我希望能够从搜索中排除一个客户,而无需添加我想保留的所有其他客户 :)

所以查询的输出应该是客户端不是{"client":["Ccc","Dddd"]}的所有文档 该数组是客户名称、位置和部门,所以下面是一个真实的例子:客户的样子:

"client":["Microsoft","Washington","Data Analytics"],
"client":["Microsoft","Washington","Hardware Devices Research Group"],
"client":["Dell","Washington","Interactive 3D", "Technologies Research Group (I3D)"],
"client":["MSI","Washington","Interactive 3D", "Media Research Group"],

我需要能够接受输入(不区分大小写)并排除所有具有该客户端的文档,因此例如,我想要所有文档,但数组元素之一等于 Interactive 3D 的文档除外(不区分大小写) ) 使用这样的查询:

db.clients.find({$text:{$search: '-interactive 3d'}})

结果将是所有只有此客户端的文档

"client":["Microsoft","Washington","Data Analytics"],
"client":["Microsoft","Washington","Hardware Devices Research Group"],

并且还能够排除所有匹配多个元素的文档 eq:microsoft washington data analytics 结果将是所有只有此客户端的文档:

"client":["Microsoft","Washington","Hardware Devices Research Group"],
"client":["Dell","Washington","Interactive 3D", "Technologies Research Group (I3D)"],
"client":["MSI","Washington","Interactive 3D", "Media Research Group"],

但我没有得到任何结果...

我使用这个取得了一些成功:

const nin = searchValue.split(' ');
db.clients.find({"client":{"$nin": nin} }) 

但它不区分大小写

【问题讨论】:

  • 查看编辑,我添加了一个真实示例

标签: node.js mongodb full-text-search


【解决方案1】:

因为你有简单的字符串数组,你可以这样做:

db.clients.find({client: {$ne: 'Dddd'}}).then(result => {
//do something with result
...
})
.catch(err => {
//do something with err
...
});

要使用多个键进行查找并进行不区分大小写的查询,您可以执行以下操作:

db.clients.find({client: {$nin: [/^Dddd$/i, /^Eeee$/i]}}).then(result => {
//do something with result
...
})
.catch(err => {
//do something with err
...
});

希望这会有所帮助:)

【讨论】:

  • 这是我的第一次尝试,但它有一些缺点,它不区分大小写,我无法搜索多个元素,如果无法使用文本索引完成,我将不得不创建另一个包含数组连接字符串并使用正则表达式的字段......但也许有人在不需要另一个字段的情况下以某种方式解决了它,而且,正则表达式比文本索引解决方案慢..
  • 要实现这一点,您可以使用 $ninregex 的组合。我已经更新了答案,你可以在那里查看:)
【解决方案2】:

我最终将$nin 与正则表达式一起使用,不知道这是可能的,但感谢这篇文章 Case Insensitive search with $in我设法解决了。

const v = searchValue.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const nin = v.split(' ');
var searchRegexp = [];
nin.forEach(function(s) {
  if (s) searchRegexp.push(new RegExp(s, 'i'));
});
db.clients.find({"client":{"$nin": searchRegexp} }) 

这样我也可以部分搜索。 我只希望它不会太慢(尚未测试)...如果有人有更好的解决方案请告诉我..

谢谢

【讨论】:

    猜你喜欢
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多