版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1433206
目录
MongoDB一个集合上只能建立一个文本索引。 建立文本索引:在集合texttest上的body键上建立文本索引。db.texttest.createIndex( { body : "text" } ); 指定索引的默认语言:db.texttest.createIndex( { body : "text" }, { default_language : "french" } ); 在多种语言上建立索引:同一集合中存在多种语言,需要有一个字段标记每个文档的语言,如下面的四个文档中的lingvo字段标识其语言。{ _id : 1, content : "cheese", lingvo : "english" }
{ _id : 2, content : "fromage", lingvo: "french" }
{ _id : 3, content : "queso", lingvo: "spanish" }
{ _id : 4, content : "ost", lingvo: "swedish" } 使用文档中给定的语言建立索引:db.textExample.createIndex( { content : "text" }, { language_override : "lingvo" } ); 建立符合索引:同时索引content和comments字段,可以在这两个字段上进行文本搜索。db.textExample.createIndex( { content : "text", comments : "text" }); 使用通配符:在全部字段上建立索引,并命名索引。db.textExample.createIndex( { "$**": "text" }, { name: "alltextindex" } ); 指定权重:指定content的权重是10,comments权重是5,其它字段的权重为1。db.textExample.createIndex( { content : "text", comments : "text"}, { weights : { content: 10, comments: 5, } } ); 同时建立文本和非文本的复合索引:content上建立文本索引,username上建立普通索引。db.textExample.createIndex( { content : "text", username : 1 }); 文本搜索:以fish为词根进行搜索,返回body中匹配fish字符串的文档。db.texttest.find({ $text : { $search :"fish" } }); 过滤结果:在文本匹配的文档中过滤出about键值为food的结果。db.texttest.find({ $text : { $search : "fish" }, about : "food" }); 复杂搜索:返回文档中body键匹配cook,但不匹配lunch的body值。先搜索所有匹配条件的数据,再删除不匹配的数据。db.texttest.find({ $text : { $search : "cook -lunch" } }, {_id:0, body:1}); 字面搜索:返回body键匹配整个字符串mongodb text search,而不是匹配mongodb、text、search这三个单词的文档。db.texttest.find({ $text : { search : "\"mongodb text search\"" } }); 限制返回的文档数:返回1条。db.texttest.find({ $text : { $search :"fish" }}).limit(1); 显示指定元素:只显示body。db.texttest.find({ $text : { $search :"fish"}}, { _id : 0, body : 1 }); 指定文本搜索使用的语言:全小写方式指定。db.texttest.find({ $text : { $search :"fish", $language : " french" } }); 利用文本与非文本的复合索引优化查询:db.texttest.createIndex( { about : 1, body : "text" });
db.texttest.find({ $text : { $search : "fish"}, about : "food"}).explain("executionStats").executionStats;db.collection.aggregate( { $group : { _id : "$color" } } ); 类比SQL:select distinct color from collection;
-- 或
select color from collection group by color;db.collection.aggregate({ $group : { _id : "$color", count : { $sum : 1 } } }); 类比SQL:select color, count(1) count from collection group by color;db.collection.aggregate({ $group : { _id : { color: "$color", transport: "$transport"} , count : { $sum : 1 } } }); 类比SQL:select color transport, count(1)
from collection
group by color, transport;db.collection.aggregate(
[
{ $group : { _id : { color: "$color", transport: "$transport"} , count : { $sum : 1 } } },
{ $limit : 5 }
]); 类比SQL:select color, transport, count(1)
from collection
group by color, transport
limit 5;db.collection.aggregate(
[
{ $match : { num : { $gt : 500 } } },
{ $group : { _id : { color: "$color", transport: "$transport"} , count : { $sum : 1 } } },
{ $limit : 5 }
]); 类比SQL:select color, transport, count(1)
from collection
where num > 500
group by color, transport
limit 5;db.collection.aggregate(
[
{ $group : { _id : { color: "$color", transport: "$transport"} , count : { $sum : 1 } } },
{ $sort : { _id :1 } },
{ $limit : 5 }
]); 类比SQL:select color, transport, count(1)
from collection
group by color, transport
order by color, transport
limit 5;db.collection.aggregate(
[
{ $match : { num : { $gt : 500 } } },
{ $group : { _id : { color: "$color", transport: "$transport"} , count : { $sum : 1 } } },
{ $sort : { _id :1 } },
{ $limit : 1 }
]); 类比SQL:select color, transport, count(1)
from collection
where num > 500
group by color, transport
order by color, transport
limit 1;db.collection.aggregate( { $unwind : "$vegetables" }); 类比SQL:select collection.*, substring_index(substring_index(vegetables, ',', id),',' ,-1) vegetables
from collection, nums -- nums为只有id一列的数字辅助表
where id <= length(vegetables)-length(replace(vegetables,',',''))+1;db.collection.aggregate(
[
{ $unwind : "$vegetables" },
{ $project : { _id: 0, fruits:1, vegetables:1 } }
]); 类比SQL:select fruits, substring_index(substring_index(vegetables, ',', id),',' ,-1) vegetables
from collection, nums -- nums为只有id一列的数字辅助表
where id <= length(vegetables)-length(replace(vegetables,',',''))+1;db.collection.aggregate(
[
{ $unwind : "$vegetables" },
{ $project : { _id: 0, fruits:1, veggies: "$vegetables" } }
]); 类比SQL:select fruits, substring_index(substring_index(vegetables, ',', id),',' ,-1) veggies
from collection, nums -- nums为只有id一列的数字辅助表
where id <= length(vegetables)-length(replace(vegetables,',',''))+1;db.collection.aggregate(
[
{ $unwind : "$vegetables" },
{ $project : { _id: 0, fruits:1, vegetables:1 } },
{ $skip : 2995 }
]); 类比SQL:select fruits, substring_index(substring_index(vegetables, ',', id),',' ,-1) vegetables
from collection, nums -- nums为只有id一列的数字辅助表
where id <= length(vegetables)-length(replace(vegetables,',',''))+1
limit 2995, 999999999;db.collection.aggregate(
[
{ $unwind : "$vegetables" },
{ $project : { _id: 0, fruits:1, vegetables:1 } },
{ $skip : 2995 },
{ $out : "food" }
]); 类比SQL:create table food as
select @a:=@a+1 id, fruits, substring_index(substring_index(vegetables, ',', id),',' ,-1) vegetables
from collection, (select @a:=0) t, nums -- nums为只有id一列的数字辅助表
where id <= length(vegetables)-length(replace(vegetables,',',''))+1
limit 2995, 999999999; db.prima.aggregate(
[
{$lookup: {
from : "secunda",
localField : "number",
foreignField : "number",
as : "secundaDoc"
} },
]); 类比SQL:select prima.*, concat(secunda.c1,secunda.c2,...secunda.cn) secundaDoc
from prima left join secunda on prima.number = secunda.number;db.prima.aggregate(
[
{$lookup:{
from : "secunda",
localField : "number",
foreignField : "number",
as : "secundaDoc" }},
{$unwind: "$secundaDoc"},
{$project: {_id : "$number", english:1, ascii:"$secundaDoc.ascii" }}
]); 类比SQL:select prima.*, secunda.*
from prima left join secunda on prima.number = secunda.number; MongoDB通过两个用户自定义的JavaScript函数实现查询:map和reduce。MongoDB将对指定的集合执行一个专门的查询,所有匹配该查询的文档都将被输入到map函数中。map函数被设计用于生成键值对。任何含有多个值的键都将被输入到reduce函数中,reduce函数将返回输入数据的聚合结果。最后,还有一个可选步骤,通过finalize函数对数据的显示进行完善。 以下是来自文档的图,可以清楚的说明 Map-Reduce 的执行过程。 定义map函数:var map = function() {
emit(this.color, this.num);
}; MongoDB中使用emit函数向MapReduce提供Key/Value对。map函数接收集合中的color和num字段作为输入,输出为以color为键,以num数组为值的文档。 定义空reduce函数:var reduce = function(color, numbers) { }; reduce函数接收map传来的键值对,但不执行任何操作。 执行MapReduce:db.mapreduce.mapReduce(map,reduce,{ out: { inline : 1 } }); { out : { inline : 1 } } 表示将执行结果输出到控制台,显示类似如下的结果。{
"results" : [
{
"_id" : "black",
"value" : null
},
{
"_id" : "blue",
"value" : null
},
...
{
"_id" : "yellow",
"value" : null
}
],
"timeMillis" : 95,
"counts" : {
"input" : 1000,
"emit" : 1000,
"reduce" : 55,
"output" : 11
},
"ok" : 1,
} 结果显示,为每种颜色创建了一个单独的文档,并且使用颜色作为文档的唯一\_id值。因为reduce函数体为空,所以value被设置为null。 定义求和reduce函数:var reduce = function(color, numbers) {
return Array.sum(numbers);
}; 该reduce函数对每个color对应的多个num求和。 执行MapReduce,并将结果输出到集合mrresult中:db.mapreduce.mapReduce(map,reduce,{ out: "mrresult" }); 查看结果集合:> db.mrresult.findOne();
{ "_id" : "black", "value" : 45318 } map函数:var map = function() {
var value = {
num : this.num,
count : 1
};
emit(this.color, value);
}; count为计数器,为了只统计每个文档一次,将count值设置为1。 reduce函数:var reduce = function(color, val ) {
reduceValue = { num : 0, count : 0};
for (var i = 0; i < val.length; i++) {
reduceValue.num += val[i].num;
reduceValue.count += val[i].count;
}
return reduceValue;
}; 用一个简单的循环对num和count求和。注意reduce函数中return函数返回的值,必须与map函数中发送到emit函数中的value结构相同。 finalize函数:var finalize = function (key, value) {
value.avg = value.num/value.count;
return value;
}; finalize函数从reduce函数接收结果,并计算平均值。 执行:db.mapreduce.mapReduce(map,reduce,{ out: "mrresult", finalize : finalize }); 查看结果:> db.mrresult.findOne();
{
"_id" : "black",
"value" : {
"num" : 45318,
"count" : 91,
"avg" : 498
}
}(1)调试map函数
重载emit函数,打印map函数的输出:var emit = function(key, value) {
print("emit results - key: " + key + " value: " + tojson(value));
} 使用map.apply和样例文档进行测试:> map.apply(db.mapreduce.findOne());
emit results - key: blue value: { "num" : 1, "count" : 1 }(2)调试reduce函数
首先需要确认map和reduce函数返回结果的格式必须严格一致。然后创建一个数组,模拟传入到reduce函数中的数组:a = [{ "num" : 1, "count" : 1 },{ "num" : 2, "count" : 1 },{ "num" : 3, "count" : 1 }] 现在调用reduce函数,显示返回结果:>reduce("blue",a);
{ "num" : 6, "count" : 3 } 如果出现某些问题,不理解函数中的内容,那么可以使用printjson()函数将JSON值输出到mongodb日志文件中。在调试时,这是一个有价值的工具。