MongoDB学习笔记6——高级查询

高级MongoDB特性是全文搜索、聚焦框架和MapReduce框架。

1)文本搜索

1-1)加载文本数据

$ mongoimport test.json -d test -c texttest  (-d表示database,-c表示collection)

1-2)创建文本索引

use test;

db.texttest.createIndex({body:"text"});

db.texttest.getIndexes()

1-3)运行文本搜索命令

db.texttest.find({$text:{$search:"fish"}})

显示查询结果,值越大相关性越大

db.texttest.find({$text:{$search:"fish"}},{score:{$meta:"textScore"}})

1-4)过滤文本查询结果

db.texttest.find({$text:{$search:"fish"},about:"food"})

1-5)更复杂的文本搜索

db.texttest.find({$text:{$search:"cook"}},{_id:0,body:1}) (0表示不显示,1表示显示)

db.texttest.find({$text:{$search:"cook -lunch"}},{_id:0,body:1}) (从搜索中排除午餐)

db.texttest.find({$text:{$search:"mongodb test search"}}) (句子中含有mongodb test search即可匹配,不管是连续还是不连续)

db.texttest.find({$text:{$search:""mongodb test search""}}) (句子中含有连续的mongodb test search才可以匹配)

1-6)额外的选项

db.texttest.find({$text:{$search:"fish"}}).limit(1)

db.texttest.find({$text:{$search:"fish",$language:"french"}}) (指定文本搜索所使用的语言)

1-7)其他语言中的文本索引

db.texttest.createIndex({body:"text"},{default_language:"french"})

注意事项:在每个集合上只能创建一个文本索引,所以在创建这个索引之前需要删除之前的文本索引。如果想要给集合中添加一个新的文本索引,就需要使用.dropIndex函数删除旧索引,其使用方式与使用createIndex函数相同。

此外。MongoDB允许在文档中指定自己的语言(english,french,spanish,swedish)

db.texttest.createIndex({content:"text"},{language_override:"lingvo"});

1-8)文本索引的复合索引

db.texttest.createIndex({content:"text",comments:"text"})

db.texttest.createIndex({"$**":"text"},{name:"alltextindex"})

设置权重:

db.texttest.createIndex({content:"text",comments:"text"},{weights:{content:10,comments:5}})

其中:相较于评论的权重5和内容的权重10,所有其他字段的默认权重都将是1。

使用非文本字段创建复合索引:

读出所有文档:

db.texttest.createIndex({content:"text",username:1})

db.texttest.find({$text:{$search:"fish"},about:"food"})explain("executionStates").executionStates;

在索引中添加about元素,可以避免出现读取所有文档的情况:

db.texttest.createIndex({about:1,body:"text"})

db.texttest.find({$text:{$search:"fish"},about:"food"})explain("executionStates").executionStates;

2)聚集框架

MongoDB中的聚集框架代表着在集合的数据上执行匹配、分组和转换操作的能力。可以使用的通配符:$group,$limit,$match,$sort,$unwind,$project,$skip,$out,$redact,$lookup

$ tar -xvf test.tgz

$ mongorestore test

db.aggregation.aggregate({pipeline document})  (创建聚集操作的通道流来实现)

2-1)$group

db.aggregation.aggregate({$group:{_id:"$color"}})

2-2)$sum

db.aggregation.aggregate({$group:{_id:"$color",count:{$sum:1}})

db.aggregation.aggregate($group:{_id:{color:"$color",transport:"$transport"},count:{$sum:1}})

2-3)$limit

db.aggregation.aggregate([$group:(_id:{color:"$color",transport:"$transport"},count:{$sum:1}}},{$limit:5}])

2-4)$match

db.aggregation.aggregate([{$match:{num:{$gt:500}}},{$group:(_id:{color:"$color",transport:"$transport"},count:{$sum:1}}},{$limit:5}])

2-5)$sort

db.aggregation.aggregate([{$group:{_id:{color:"$color",transport:"$transport"},count:{$sum:1}}},{$sort:{_id:1}},{$limit:5}])

2-6)$unwind

使用$unwind将接受一个数组并将每个元素分割到一个新的文档中(在内存中而不是添加到集合中)。

db.aggregation.aggregate({$unwind:"$vegetables"})

$project

db.aggregation.aggregate([{$unwind:"$vegetables"},{$project:{_id:0,fruits:1,vegetables:1}}])

2-7)$skip

db.aggregation.aggregate([{$unwind:"$vegetables"},{$project:{_id:0,fruits:1,vegetables:1}},{$skip:2995}])

2-8)$out

这个操作符允许把操作输出到集合中,而不是直接返回结果。

db.aggregation.aggregate([{$unwind:"$vegetables"},{$project:{_id:0,fruits:1,vegetables:1}},{$skip:2995}},{$out:"food"}])

2-9)$lookup

db.prima.insert({number:1,english:"one"})

db.prima.insert({number:2,english:"two"})

db.secunda.insert({number:1,ascii:49})

db.secunda.insert({number:2,ascii:50})

db.prima.aggregate([

{$lookup:{

from:"secunda",

localField:"number",

foreignField:"number",

as:"secundaDoc"

}},

])

简化输出:

db.prima.aggregate([

{$lookup:{

from:"secunda",

localField:"number",

foreignField:"number",

as:"secundaDoc"

}},

{$unwind:"$secundaDoc"},

{$project:{_id:"$number",english:1,ascii:"secundaDoc.ascii"}}

])

3)MapReduce

MapReduce通过两个JavaScript函数实现查询:map和reduce,这两个函数完全由用户自定义。map函数被设计用于生成键/值对。任何含有多个值的键都将输入到reduce函数中,reduce函数将返回输入数据的聚集结果。此后,还有一个可选的步骤,通过finalize函数对数据的显示进行完善。

3-1)使用map函数

var map = function(){

emit(this.color,this.num);

}

var reduce = function(color,numbers){};

将结果输出到控制台,将文档中out选项的值设置为{inline:1}

db.mapreduce.mapReduce(map,reduce,{out:{inline:1}})

将结果输出到集合mrresult中

var reduce = function(color,numbers){

return Array.sum(numbers);

}

db.mapreduce.mapReduce(map,reduce,{out:"mrresult"})

db.mrresult.findOne();

3-2)高级MapReduce

var map = function(){

var value = {

num : this.num,

count : 1

};

emit(this.color,value)

}

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;

}

db.mapreduce.mapReduce(map,reduce,{out:"mrresult"})

db.mrresult.findOne();

var finailize = function(key,value){

value.avg = value.num / value.count;

return value;

}

db.mapreduce.mapReduce(map,reduce,{out:"mrresult",finalize:finalize})

db.mrresult.findOne()

3-3)调试MapReduce

如果出现某种问题,不理解函数中的内容,那么可以使用printjson()函数将JSON值输出到mongoDB日志文件中。

var emit = function(key,value){

print("emit result -key:" + key + "value:" + tojson(value));

}

map.apply(db.mapreduce.findOne())

a = [{"num":1,"count":1},{"num":2,"count":1},{"num":3,"count":1}]

reduce("blue",a)

原文地址:https://www.cnblogs.com/zhuozige/p/12485856.html