我查看了MongoDB文档并搜索了这个问题,但无法找到合适的答案。所以,这就是我要找的东西。 假设我有一个包含这样的元素的集合:
{
"foo" : "bar",
"test" : "test",
"key" : "value",
}
我想要实现的是通过搜索所有(可能除了有限多个;-))字段来找到一个元素。换句话说:给定查询,我不知道应该在哪个字段中找到查询。
我的想法是这样的
db.things.find({_ANY_ : "bar"})
会给我示例元素。
感谢您的帮助。
答案 0 :(得分:27)
要对所有字段进行文本搜索,首先必须在所有字段上创建文本索引。
,如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> } });
有关控制搜索的各种方法的详细信息,请参阅有关文本搜索的mongodb文档here
答案 1 :(得分:25)
如果没有单独检查应用程序文档或通过服务器端代码执行,这是不可能的。请考虑将架构更改为:
{params:[{field:"foo", value:"bar"}, {field:"test", value:"test"}, {field:"key", value:"value"}]}
这显然有一些缺点(主要是性能和复杂的架构)但会允许你需要的东西:
db.things.find({'params.value':"bar"})
答案 2 :(得分:20)
This answer对于类似的问题有你的解决方案,为了完整起见,我将在此重复。您可以使用$where
运算符在MongoDB服务器上运行任意JavaScript,但需要注意的是,这将比几乎任何其他类型的查询慢得多。对于您的示例,它将是:
db.things.find({$where: function() {
for (var key in this) {
if (this[key] === "bar") {
return true;
}
return false;
}
}});
答案 3 :(得分:15)
可悲的是,之前的答案都没有解决mongo可以在数组或嵌套对象中包含嵌套值的事实。
这是正确的查询:
{$where: function() {
var deepIterate = function (obj, value) {
for (var field in obj) {
if (obj[field] == value){
return true;
}
var found = false;
if ( typeof obj[field] === 'object') {
found = deepIterate(obj[field], value)
if (found) { return true; }
}
}
return false;
};
return deepIterate(this, "573c79aef4ef4b9a9523028f")
}}
由于在数组或嵌套对象上调用typeof将返回&#39; object&#39;这意味着查询将迭代所有嵌套元素,并将遍历所有嵌套元素,直到找到具有值的键。
您可以使用嵌套值检查以前的答案,结果将远非理想。
对整个对象进行字符串化的效果要差得多,因为它必须逐个遍历所有内存扇区并尝试匹配它们。并在ram内存中创建一个对象的副本作为一个字符串(由于函数上下文已经有一个加载的对象,因此查询使用更多的ram和慢速都是低效的)
答案 4 :(得分:2)
您可以使用递归函数执行此操作:
var recursiveSearch = function(query) {
db.test_insert.find().forEach(function(items) {
var i = 0;
var recursiveFunc = function(itemsArray, itemKey) {
var itemValue = itemsArray[itemKey];
if(itemValue === query) {
printjson(items);
}
if(typeof itemValue === "object") {
Object.keys(itemValue).forEach(function(itemValueKey) {
recursiveFunc(itemValue, itemValueKey);
});
}
};
Object.keys(items).forEach(function(item){
recursiveFunc(items, item);
});
});
};
recursiveSearch('your string');
答案 5 :(得分:2)
要进行文本搜索,您必须为集合创建文本索引。 有关更多信息,请查看mongo文档:indexes text
答案 6 :(得分:1)
使用$where与执行全表扫描相同,不能使用索引。我也无法让它工作,但我确实发现它有效(它也相当于全表扫描):
db.collection.find().forEach(function(doc){
for (var key in doc) {
if ( /needle/.test(doc[key]) )
printjson(doc);
}
});
其中/needle/
是要在doc[key]
答案 7 :(得分:-8)
{
"foo" : "bar",
"test" : "test",
"key" : "value",
}
db.collection_name.find({'foo':"bar"})