MongoDB查询

查询概要

 MongoDB 查询数据的语法格式如下:
     db.collection.find(query, projection)
 query :可选,使用查询操作符指定查询条件
 projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。需要以易读的方式来读取数据,可以使用 pretty() 方法;

查询选择器

177d563f11ac4ea1b21e28f64707a6b3614.jpg

(1)in语句示例:
db.users.find({"username":{"$in":["lison","sean"]}})

(2)not语句示例:
db.users.find({"lenght":{"$not":{"$gte":1.77}}}).pretty()
因为not语句 会把不包含查询语句字段的文档 也检索出来

(3)exists语句示例:
db.users.find({"lenght":{"$exists":true}}).pretty()
判断文档有没有关心的字段

查询选择

 映射
     字段选择:db.users.find({},{'username':1})
     字段排除:db.users.find({},{'username':0})
 排序
     sort():db.orders.find().sort({'orderTime':1,'price':1})1:升序 -1:降序
 跳过和限制
     skip(n):跳过n条数据
     limit(n):限制n条数据
        e.g:db.orders.find().sort({'orderTime':-1}).limit(5).skip(5)
 查询唯一值
     distinct():查询指定字段的唯一值,e.g:db.users.distinct(“age”)

测试数据

var user1 = {
        "username" : "lison",
        "country" : "china",
        "address" : {
                "aCode" : "411000",
                "add" : "长沙"
        },
        "favorites" : {
                "movies" : ["杀破狼2","战狼","雷神1"],
                "cites" : ["长沙","深圳","上海"]
        },
        "age" : 18,
	   "salary":NumberDecimal("18889.09"),
       "lenght" :1.79,
	   "comments" :  [
				{
					"author"  :  "lison1",
					"content"  :  "lison评论1",
					"commentTime" : ISODate("2017-01-06T04:26:18.354Z")
				},
				{
					"author"  :  "lison2",
					"content"  :  "lison评论2",
					"commentTime" : ISODate("2017-02-06T04:26:18.354Z")
				},
				{
					"author"  :  "lison3",
					"content"  :  "lison评论3",
					"commentTime" : ISODate("2017-03-06T04:26:18.354Z")
				},
				{
					"author"  :  "lison4",
					"content"  :  "lison评论4",
					"commentTime" : ISODate("2017-04-06T04:26:18.354Z")
				},
				{
					"author"  :  "lison5",
					"content"  :  "lison是苍老师的小迷弟",
					"commentTime" : ISODate("2017-05-06T04:26:18.354Z")
				},
				{
					"author"  :  "lison6",
					"content"  :  "lison评论6",
					"commentTime" : ISODate("2017-06-06T04:26:18.354Z")
				},
				{
					"author"  :  "lison7",
					"content"  :  "lison评论7",
					"commentTime" : ISODate("2017-07-06T04:26:18.354Z")
				},
				{
					"author"  :  "lison8",
					"content"  :  "lison评论8",
					"commentTime" : ISODate("2017-08-06T04:26:18.354Z")
				},
				{
					"author"  :  "lison9",
					"content"  :  "lison评论9",
					"commentTime" : ISODate("2017-09-06T04:26:18.354Z")
				}
		]
	    
};

字符串数组选择查询

1.数组单元素查询
    db.users.find({"favorites.movies":"蜘蛛侠"})
    查询数组中包含“蜘蛛侠”
2.数组精确查找
    db.users.find({"favorites.movies":[ "杀破狼2", "战狼", "雷神1" ]},{"favorites.movies":1})
    查询数组等于[ “杀破狼2”, “战狼”, “雷神1” ]的文档,严格按照顺序;
3.数组多元素查询
    db.users.find({"favorites.movies":{"$all":[ "雷神1", "战狼" ]}},{"favorites.movies":1})
    查询数组包含[“雷神1”, “战狼” ]的文档,跟顺序无关
4.索引查询
    db.users.find({"favorites.movies.0":"杀破狼2"},{"favorites.movies":1})
    查询数组中第一个为“杀破狼2”的文档
5.返回数组子集
    db.users.find({},{"favorites.movies":{"$slice":[1,2]},"favorites":1})
    $slice可以取两个元素数组,分别表示从几条开始和显示的条数;

对象数组选择查询

1. 单元素查询
    db.users.find({"comments":{"author" : "lison6","content" : "lison评论6"}})
    备注:对象数组精确查找
2.查找lison1 或者 lison12评论过的user ($in查找符)
    db.users.find({"comments.author":{"$in":["lison1","lison12"]}}).pretty()
    备注:跟数量无关,跟顺序无关;
3.查找lison1 和 lison12都评论过的user
    db.users.find({"comments.author":{"$all":["lison12","lison1"]}}).pretty()
    备注:跟数量有关,跟顺序无关;
4.查找lison5评语为“lison是苍老师的小迷弟”的user($elemMatch查找符)
    db.users.find({"comments":{"$elemMatch":{"author" : "lison5","content" : "lison是苍老师的小迷弟"}}}) .pretty()
    备注:数组中对象数据要符合查询对象里面所有的字段,$全元素匹配,和顺序无关;

 

查询练习

 需求描述
     查看一个人的信息,打开页面只显示三条评论
     点击评论的下一页按钮,新加载三条评论
     默认按照评论时间降序

 解决方案描述
    1. 新增评论时,使用$sort运算符进行排序,插入评论后,再按照评论时间降序排序;
    2. 查看人员时加载最新的三条评论;
    3. 点击评论的下一页按钮,新加载三条评论
    4. 如果有多种排序需求怎么处理?

实训脚本:
(1)新增评论时,使用$sort运算符进行排序,插入评论后,再按照评论时间降序排序;
    
			db.users.updateOne({"username":"lison",},
					{
					  "$push": {
						 "comments": {
						   $each: [
								{
									"author" : "james",
									"content" : "lison是个好老师!",
									"commentTime" : ISODate("2018-01-06T04:26:18.354Z")
								}
							],
						   $sort: {"commentTime":-1}
						 }
					  }
					}
				);
				
	注意:$sort操作符必须和$each配合使用

(2)查看人员时加载最新的三条评论;
	db.users.find({"username":"lison"},{"comments":{"$slice":[0,3]}}).pretty()
	
(3)点击评论的下一页按钮,新加载三条评论
    原方法:db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$elemMatch":""}).pretty();
	新的方法:db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$id":1}).pretty();
	


(4)如果有多种排序需求怎么处理?使用聚合
db.users.aggregate([{"$match":{"username":"lison"}},
                    {"$unwind":"$comments"},
					{$sort:{"comments.commentTime":-1}},
					{"$project":{"comments":1}},
					{"$skip":6},
					{"$limit":3}])
----------------------------------------------------------------
聚合训练:
查询2015年4月3号之前,每个用户每个月消费了多少钱,并按用户名进行排序:
db.ordersTest.aggregate([
                          {"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}}, 
						  {"$group":{"_id":{"useCode":"$useCode","month":{"$month":"$orderTime"}},"total":{"$sum":"$price"}}}, 
						  {"$sort":{"_id":1}}    
						])

原生Document方式

@Configuration
public class AppConfig {

  /*
   * Use the standard Mongo driver API to create a com.mongodb.MongoClient instance.
   */
	@Bean
   public MongoClient mongoClient() {
	   
//   	CodecRegistry registry = CodecRegistries.fromRegistries(MongoClient.getDefaultCodecRegistry(),
//       CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build()));

		MongoClientOptions mco = MongoClientOptions.builder()
				.writeConcern(WriteConcern.ACKNOWLEDGED)
				.connectionsPerHost(100)
				.threadsAllowedToBlockForConnectionMultiplier(5)
				.maxWaitTime(120000).connectTimeout(10000).build();

	   MongoClient client = new MongoClient(new ServerAddress("120.78.154.33", 27022), mco);
       return client;
   }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JavaDriverTest {

	private static final Logger logger = LoggerFactory.getLogger(JavaDriverTest.class);
	
    private MongoDatabase db;


    private MongoCollection<Document> collection;
    
    @Resource
    private MongoClient client;
    
    
    @Before
    public void init(){
	    	db = client.getDatabase("lison");
	    	collection=db.getCollection("users");
    }
    
    
    @Test
    //测试elemMatch操作符,数组中对象数据要符合查询对象里面所有的字段
    //查找lison5评语为“lison是苍老师的小迷弟”的人
    //db.users.find({"comments":{"$elemMatch":{"author" : "lison5","content" : "lison是苍老师的小迷弟"}}}) .pretty()
    public void testElemMatch(){
       	//定义数据的处理类
    	final List<Document> ret = new ArrayList<>();
    	Block<Document> printBlock = getBlock(ret);
    	//
    	Document filter = new Document().append("author","lison5")
    			                        .append("content","lison是苍老师的小迷弟");
		Bson elemMatch = Filters.elemMatch("comments",filter );

    	FindIterable<Document> find = collection.find(elemMatch);
    	
    	printOperation(ret, printBlock, find);
    	
    }
    
    /**
     * 			db.users.updateOne({"username":"lison",},
					{"$push": {
						 "comments": {
						   $each: [{
									"author" : "james",
									"content" : "lison是个好老师!",
									"commentTime" : ISODate("2018-01-06T04:26:18.354Z")
								}
							],
						   $sort: {"commentTime":-1}
						 }}});
     */
    @Test
    //新增评论时,使用$sort运算符进行排序,插入评论后,再按照评论时间降序排序
    public void demoStep1(){
    	Bson filter = eq("username", "lison");
    	Document comment = new Document().append("author","cang")
                						 .append("content","lison是我的粉丝")
                						 .append("commentTime", new Date());
    	//$sort: {"commentTime":-1}
    	Document sortDoc = new Document().append("commentTime", -1);
    	PushOptions sortDocument = new PushOptions().sortDocument(sortDoc);
    	// $each
		Bson pushEach = Updates.pushEach("comments", Arrays.asList(comment), sortDocument);
		
		
		UpdateResult updateOne = collection.updateOne(filter, pushEach);
		System.out.println(updateOne.getModifiedCount());
    }
    @Test
    //查看人员时加载最新的三条评论;
    //db.users.find({"username":"lison"},{"comments":{"$slice":[0,3]}}).pretty()
    public void demoStep2(){
    	final List<Document> ret = new ArrayList<>();
    	Block<Document> printBlock = getBlock(ret);
		
		FindIterable<Document> find = collection.find(eq("username", "lison"))
                								.projection(slice("comments", 0, 3));
		printOperation(ret, printBlock, find);
    }

    
    @Test
    //点击评论的下一页按钮,新加载三条评论
    //db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$id":1}).pretty();
    public void demoStep3(){
    	final List<Document> ret = new ArrayList<>();
    	Block<Document> printBlock = getBlock(ret);
		
		//{"username":"lison"}
		Bson filter = eq("username", "lison");
		//"$slice":[3,3]
		Bson slice = slice("comments", 3, 3);
		//"$id":1
		Bson includeID = include("id");
		
		//{"comments":{"$slice":[3,3]},"$id":1})
		Bson projection = fields(slice,includeID);
		
		FindIterable<Document> find = collection.find(filter)
                								.projection(projection);
		printOperation(ret, printBlock, find);
    }


    @Test
    /**
     * db.users.aggregate([{"$match":{"username":"lison"}},
                           {"$unwind":"$comments"},
	                       {$sort:{"comments.commentTime":-1}},
	                       {"$project":{"comments":1}},
	                       {"$skip":6},
	                       {"$limit":3}])
     */
    //如果有多种排序需求怎么处理,使用聚合
    public void demoStep4(){
    	final List<Document> ret = new ArrayList<>();
    	Block<Document> printBlock = getBlock(ret);
    	List<Bson> aggregates = new ArrayList<>();
    	
    	aggregates.add(match(eq("username","lison")));
    	aggregates.add(unwind("$comments"));
    	aggregates.add(sort(orderBy(ascending("comments.commentTime"))));
    	aggregates.add(project(fields(include("comments"))));
    	aggregates.add(skip(0));
    	aggregates.add(limit(3));
    	
    	AggregateIterable<Document> aggregate = collection.aggregate(aggregates);
    	
		printOperation(ret, printBlock, aggregate);
    }
    
    
    //dbRef测试
    //dbref其实就是关联关系的信息载体,本身并不会去关联数据
    @Test
    public void dbRefTest(){
    	final List<Document> ret = new ArrayList<>();
    	Block<Document> printBlock = getBlock(ret);
    	FindIterable<Document> find = collection.find(eq("username", "lison"));
		printOperation(ret, printBlock, find);
    }


//---------------------------------------------------------------------------

	private void printOperation(List<Document> ret, Block<Document> printBlock,
			AggregateIterable<Document> aggregate) {
		aggregate.forEach(printBlock);
		System.out.println(ret.size());
		ret.removeAll(ret);
		
	}


	private void printOperation(final List<Document> ret,
			Block<Document> printBlock, FindIterable<Document> find) {
		find.forEach(printBlock);
		System.out.println(ret.size());
		ret.removeAll(ret);
	}
	
	private Block<Document> getBlock(final List<Document> ret) {
		Block<Document> printBlock = new Block<Document>() {
			@Override
			public void apply(Document t) {
				logger.info("---------------------");
//				logger.info(t.toJson());
				Object object = t.get("comments");
				System.out.println(object);
				logger.info("---------------------");
				ret.add(t);
			}
		};
		return printBlock;
	}
    
    

}

Spring方式

@Document(collection="users")
public class User {
	
	private ObjectId id;
		
	private String username;
	
	private String country;
	
	private Address address;
	
	private Favorites favorites;
	
	private int age;
	
	private BigDecimal salary;
	
	private float lenght;
	
	@DBRef
	private Comments comments;
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getCountry() {
		return country;
	}
	public void setCountry(String country) {
		this.country = country;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	public Favorites getFavorites() {
		return favorites;
	}
	public void setFavorites(Favorites favorites) {
		this.favorites = favorites;
	}
	public ObjectId getId() {
		return id;
	}
	public void setId(ObjectId id) {
		this.id = id;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public BigDecimal getSalary() {
		return salary;
	}
	public void setSalary(BigDecimal salary) {
		this.salary = salary;
	}
	public float getLenght() {
		return lenght;
	}
	public void setLenght(float lenght) {
		this.lenght = lenght;
	}
	public Comments getComments() {
		return comments;
	}
	public void setComments(Comments comments) {
		this.comments = comments;
	}

	
	
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {

	private static final Logger logger = LoggerFactory
			.getLogger(SpringTest.class);

	@Resource
	private MongoOperations tempelate;

	@Test
	// db.users.find({"comments":{"$elemMatch":{"author" : "lison5","content" :
	// "lison是苍老师的小迷弟"}}}) .pretty()
	public void testElemMatch() {
		Query query = query(where("comments").elemMatch(where("author").is("lison5").and("content").is("lison是苍老师的小迷弟")));
		List<User> find = tempelate.find(query, User.class);
		System.out.println(find.size());

	}

    /**
     * 			db.users.updateOne({"username":"lison",},
					{"$push": {
						 "comments": {
						   $each: [{
									"author" : "james",
									"content" : "lison是个好老师!",
									"commentTime" : ISODate("2018-01-06T04:26:18.354Z")
								}
							],
						   $sort: {"commentTime":-1}
						 }}});
     */
	@Test
	// 新增评论时,使用$sort运算符进行排序,插入评论后,再按照评论时间降序排序
	public void demoStep1() {
		Query query = query(where("username").is("lison"));
		Comment comment = new Comment();
		comment.setAuthor("cang");
		comment.setCommentTime(new Date());
		comment.setContent("lison是我的粉丝");

		Update update = new Update();
		PushOperatorBuilder pob = update.push("comments");
		pob.each(comment);
		pob.sort(new Sort(new Sort.Order(Direction.DESC, "commentTime")));
		
		System.out.println("---------------");
		WriteResult updateFirst = tempelate.updateFirst(query, update,User.class);
		System.out.println("---------------");
		System.out.println(updateFirst.getN());
	}

	@Test
	// 查看人员时加载最新的三条评论;
	// db.users.find({"username":"lison"},{"comments":{"$slice":[0,3]}}).pretty()
	public void demoStep2() {
		//{"username":"lison"}
		Query query = query(where("username").is("lison"));
		//{"comments":{"$slice":[0,3]}
		query.fields().include("comments").slice("comments", 0, 3);
		System.out.println("---------------");
		List<User> find = tempelate.find(query, User.class);
		System.out.println("---------------");
		System.out.println(find);
	}

	@Test
	// 点击评论的下一页按钮,新加载三条评论
	// db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$id":1}).pretty();
	public void demoStep3() {
		Query query = query(where("username").is("lison"));
		query.fields().include("comments").slice("comments", 3, 3)
				.include("id");
		System.out.println("---------------");
		List<User> find = tempelate.find(query, User.class);
		System.out.println("---------------");
		System.out.println(find);
	}

	
	/**
	 * db.users.aggregate([{"$match":{"username":"lison"}},
	                       {"$unwind":"$comments"},
	                       {$sort:{"comments.commentTime":-1}},
	                       {"$project":{"comments":1}},
	                       {"$skip":6},
	                       {"$limit":3}])
	                       
	 */
	// 如果有多种排序需求怎么处理,使用聚合
	@Test
	public void demoStep4() {
		Aggregation aggs = newAggregation(
				match(where("username").is("lison")),
				unwind("comments"),
				sort(Direction.ASC, "comments.commentTime"),
				project("comments"), 
				skip(6), 
				limit(3));
		System.out.println("---------------");
		AggregationResults<Object> aggregate = tempelate.aggregate(aggs, "users",	Object.class);
		System.out.println("---------------");
		List<Object> mappedResults = aggregate.getMappedResults();
		System.out.println(mappedResults.size());

	}
	
	@Test
	//(1)注意相关的实体bean要加上注解@document,@dbRef
	//(2)spring对dbRef进行了封装,发起了两次查询请求
	public void dbRefTest(){
		System.out.println("----------------------------");
		List<User> users = tempelate.findAll(User.class);
		System.out.println("----------------------------");
		System.out.println(users);
//		System.out.println(users.get(0).getComments());
	}



}

当出现对同一个属性进行投影时,只会执行最后一个投影操作。

查看一个人的信息,打开页面只显示三条评论,实现的语句:
db.users.find({"username":"lison"},{"comments":{"$slice":[0,3]}}).pretty()
点击评论的下一页按钮,新加载三条评论,实现的查询语句:
不推荐:db.users.find({"username":"lison"},{"comments.lists":{"$slice":[0,3]},"comments":1}).pretty()
推荐:db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$elemMatch":""}).pretty()

PS

1.SPRING 写入的数据,_class字段修改后是否会影响到实体类的生成验证
答:修改对代码没有影响

2.convert代码示例

答:spring 1.x版本没有提供对mongo decemal128数据默认的支持,所以需要自定义转换器进行转换;

spring 配置示例

	<!-- mongodb连接池配置 -->
	<mongo:mongo-client host="192.168.225.129" port="27022">
		<mongo:client-options 
		      write-concern="ACKNOWLEDGED"
		      connections-per-host="100"
		      threads-allowed-to-block-for-connection-multiplier="5"
		      max-wait-time="120000"
			  connect-timeout="10000"/> 
	</mongo:mongo-client>
	
	<!-- mongodb数据库工厂配置 -->
	<mongo:db-factory dbname="test" mongo-ref="mongo" />
	
 	<mongo:mapping-converter base-package="com.dongnao.mongodb.entity">
	  <mongo:custom-converters>
	      <mongo:converter>
	        <bean class="com.dongnao.mongo.convert.BigDecimalToDecimal128Converter"/>
	      </mongo:converter>
	      <mongo:converter>
	        <bean class="com.dongnao.mongo.convert.Decimal128ToBigDecimalConverter"/>
	      </mongo:converter>
    </mongo:custom-converters>
	
	</mongo:mapping-converter>

    <!-- mongodb模板配置 -->
	<bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
		<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
		<constructor-arg name="mongoConverter" ref="mappingConverter"/>
		<property name="writeResultChecking" value="EXCEPTION"></property>
	</bean>

Java客户端解析

 原生java驱动

 MongoClient → MongoDatabase →MongoCollection
    • MongoClient被设计成线程安全、可以被多线程共享的。通常访问数据库集群的应用只需要一个实例
    • 如果需要使用pojo对象读写,需要将PojoCodecProvider注入到client中
 查询和更新的API类
    查询器:com.mongodb.client.model.Filters
    投影器:com.mongodb.client.model.Projections
    更新器:com.mongodb.client.model.Updates

构造器模式的理解:https://www.jianshu.com/p/e2a2fe3555b9

public class User {

    private final String firstName;     // 必传参数
    private final String lastName;      // 必传参数
    private final int age;              // 可选参数
    private final String phone;         // 可选参数
    private final String address;       // 可选参数

    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    public String getPhone() {
        return phone;
    }

    public String getAddress() {
        return address;
    }

    public static class UserBuilder {
        private final String firstName;
        private final String lastName;
        private int age;
        private String phone;
        private String address;

        public UserBuilder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }

        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }

        public UserBuilder address(String address) {
            this.address = address;
            return this;
        }

        public User build() {
            return new User(this);
        }
    }
}

作者:湫水长天
链接:https://www.jianshu.com/p/e2a2fe3555b9
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Mongodb连接池配置

bbf59716c127b16bcef160a600afa1a4fd4.jpg

bc4459e91910955e7bb8c80bf06c42373fb.jpg

数据模式设计

0a882e91e4a7993b946acc749b57e7507ea.jpg

nosql在数据模式设计上的优势

 读写效率高-在IO性能上有先天独厚的优势;
 可扩展能力强,不需要考虑关联,数据分区分库,水平扩展就比较简单;
 动态模式,不要求每个文档都具有完全相同的结构。对很多异构数据场景支持非常好;
 模型自然-文档模型最接近于我们熟悉的对象模型;

mongoDB能不能实现关联查询?

 先考虑内嵌, 直接按照你的对象模型来设计你的数据模型。如果你的对象模型数量不多,关系不是很复杂,直接一种对象对应一个集合就可以了
  单个bson 文档最大不能超过16M ;当文档超过16M的时候,就应该考虑使用引用(DBRef)了,在主表里存储一个id值,指向另一个表中的 id 值。
    DBRef语法:{ "$ref" : <value>, "$id" : <value>, "$db" : <value> }
        $ref:引用文档所在的集合的名称;
        $id:所在集合的_id字段值;
        $db:可选,集合所在的数据库实例;

    使用dbref脚本示例:

       var lison = db.users.findOne({"username":"lison"});
        var dbref = lison.comments;
        db[dbref.$ref].findOne({"_id":dbref.$id})

 

聚合的理解

 聚合框架就是定义一个管道,管道里的每一步都为下一步输出数据数据

a3823686b0f005c2d39a50f13bff9175438.jpg

 常用的管道操作

 $project:投影,指定输出文档中的字段;
 $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作
 $limit:用来限制MongoDB聚合管道返回的文档数。
 $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
 $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
 $group:将集合中的文档分组,可用于统计结果。
 $sort:将输入文档排序后输出。

$group操作符

 $group:可以分组的数据执行如下的表达式计算:
 $sum:计算总和。
 $avg:计算平均值。
 $min:根据分组,获取集合中所有文档对应值得最小值。
 $max:根据分组,获取集合中所有文档对应值得最大值。
 $push:将指定的表达式的值添加到一个数组中。
 $addToSet:将表达式的值添加到一个集合中(无重复值)。
 $first:返回每组第一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序的第一个文档。
 $last:返回每组最后一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序的最后个文档

聚合训练

 查询2015年4月3号之前,每个用户每个月消费的总金额,并按用户名进行排序:
db.ordersTest.aggregate([
        {"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
        {"$group":{"_id":{"useCode":"$useCode","month":{"$month":"$orderTime"}},"total":{"$sum":"$price"}}},
        {"$sort":{"_id":1}}
])

736e567a0a039b90e54d43860419e3abe48.jpg

转载于:https://my.oschina.net/u/3728166/blog/2221460

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值