我浏览了MongoDB的文档,在Google上搜索了这个问题,但没有找到合适的答案。所以,下面是我要找的。假设我有一个包含如下元素的集合:
{
"foo" : "bar",
"test" : "test",
"key" : "value",
}
我想要实现的是通过在所有元素中搜索来找到一个元素(可能除了有限多个元素;- ))字段。换句话说:给定一个查询,我不知道应该在哪个字段中找到该查询。
在我看来
db.things.find({_ANY_ : "bar"})
会给我一个示例元素。
谢谢你的帮助。
8条答案
按热度按时间qaxu7uf21#
要在所有字段上执行文本搜索,首先必须在所有字段上创建文本索引。
如mongodb documentation所示,“要允许对所有包含字符串内容的字段进行文本搜索,请使用通配符说明符($**)来索引所有包含字符串内容的字段。”
如果你在mongo shell里面工作(你可以通过调用'mongo'从命令行执行),那么你可以用这个命令来完成它,其中'collection'是你想要使用的数据库中的集合的名称。
db.collection.createIndex({ "$**": "text" },{ name: "TextIndex" })
第二个对象,即
{name:"TextIndex"}
,是可选的......实际上不需要给予索引命名,因为每个集合只能有一个文本索引(一次......如果需要,可以删除索引并创建新的索引)。在所有字段上创建文本索引后,可以使用以下查询对象执行简单的文本搜索:
{ $text : { $search: <your string> } }
因此,如果你正在编写一个javascript函数,你可能会这样做:
var cursor = db.collection(<collection_name>).find({ $text: { $search: <your string> } });
要获得更多关于控制搜索的各种方法的信息,请参见文本搜索here的mongodb文档
yks3o0rb2#
类似问题的This answer有您的解决方案,为了完整起见,我将在这里重复。您可以使用
$where
操作符在MongoDB服务器上运行任意JavaScript,但要注意的是,这将比几乎任何其他类型的查询都要慢得多。对于您的示例,它将是:myzjeezk3#
如果不在应用程序端或通过服务器端代码执行单独检查文档,则无法执行此操作。请考虑将架构更改为:
这显然有一些缺点(主要是性能和poluted schema),但可以通过以下方式满足您的需要:
zpgglvta4#
遗憾的是,前面的答案都没有解决mongo可以在数组或嵌套对象中包含嵌套值这一事实。
这是正确的问题:
由于在数组或嵌套对象上调用typeof将返回'object',这意味着查询将在所有嵌套元素上迭代,并将迭代所有元素,直到找到具有值的键。
您可以使用嵌套值检查以前的答案,结果将远远不是所期望的。
字符串化整个对象的性能要差得多,因为它必须一个接一个地遍历所有内存扇区,并在ram内存中创建一个字符串形式的对象副本(效率低,因为查询使用了更多的ram;速度慢,因为函数上下文已经加载了一个对象)
fiei3ece5#
使用$where和执行全表扫描是一样的,不能使用索引。我也不能让它工作,但是我发现它工作了(它也相当于全表扫描):
其中
/needle/
是要在doc[key]
的值中查找的正则表达式s3fp2yjn6#
你可以用递归函数来实现:
zazmityj7#
要进行文本搜索,你必须为你的集合创建文本索引。要了解更多信息,请查看mongo文档:indexes text
az31mfrm8#
对MongoDB进行快速而粗略的全数据库搜索是通过export将数据库导出到JSON和
grep
:当然,搜索词将同时匹配键名和值,但有时候这甚至很方便(例如,开发人员试图在大型文档的文档结构更改后查找字段)。
这种解决方案对于大规模数据库来说效率非常低,但是在只有测试数据的开发过程中非常方便。
MongoDB导出到JSON的源代码是Tom Boutell's answer for "How to export all collections in MongoDB?",包含更多细节和解释。