MongoDB使用记录

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB使用记录相关的知识,希望对你有一定的参考价值。

最近爬虫项目在做主题分类的时候需要将爬去规则存到MongoDB中。后台需要集成MongoDB。这里记录一下使用MongoDB的过程。

Spring Data MongoDB - Reference Documentation地址:

  http://docs.spring.io/spring-data/data-mongodb/docs/current/reference/html/

 

1.项目集成MongoDB

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-mongodb</artifactId>
	<version>1.3.2.RELEASE</version>
</dependency>

 

2.编写MongoDB基础操作类

技术分享
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.mongodb.WriteResult;

/**
 * mongodb 基础操作类
 * 
 * @author yangkun
 * 
 */
public abstract class MongoBaseDao<T> {

    @Autowired
    @Qualifier("mongoTemplate")
    public MongoTemplate mongoTemplate;
    
    private Class<T> entityClass;
    
    /**
     * 初始化DAO时使用反射拿到泛型超类的类型参数
     */
    @SuppressWarnings("unchecked")
    public MongoBaseDao() {
        this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /**
     * 通过条件查询,查询分页结果
     * 
     * @param pageNo
     * @param pageSize
     * @param query
     * @return
     */
    public Pagination<T> getPage(int pageNo, int pageSize, Query query) {
        long totalCount = this.mongoTemplate.count(query, this.entityClass);
        Pagination<T> page = new Pagination<T>(pageNo, pageSize, totalCount);
        query.skip(page.getFirstResult());// skip相当于从那条记录开始
        query.limit(pageSize);// 从skip开始,取多少条记录
        List<T> datas = this.find(query);
        page.setDatas(datas);
        return page;
    }

    /**
     * 通过条件查询实体(集合)
     * 
     * @param query
     */
    public List<T> find(Query query) {
        return mongoTemplate.find(query, this.entityClass);
    }

    /**
     * 通过一定的条件查询一个实体
     * 
     * @param query
     * @return
     */
    public T findOne(Query query) {
        return mongoTemplate.findOne(query, this.entityClass);
    }

    /**
     * 查询出所有数据
     * 
     * @return
     */
    public List<T> findAll() {
        return this.mongoTemplate.findAll(this.entityClass);
    }

    /**
     * 查询并且修改记录
     * 
     * @param query
     * @param update
     * @return
     */
    public T findAndModify(Query query, Update update) {
        return this.mongoTemplate.findAndModify(query, update, this.entityClass);
    }

    /**
     * 按条件查询,并且删除记录
     * 
     * @param query
     * @return
     */
    public T findAndRemove(Query query) {
        return this.mongoTemplate.findAndRemove(query, this.entityClass);
    }

    /**
     * 通过条件查询更新数据
     * 
     * @param query
     * @param update
     * @return
     */
    public void updateFirst(Query query, Update update) {
        mongoTemplate.updateFirst(query, update, this.entityClass);
    }

    /**
     * 更新多个
     * @param query
     * @param update
     */
    public int updateMulti(Query query, Update update) {
        WriteResult result = mongoTemplate.updateMulti(query, update, this.entityClass);
        return result.getN();
    }
    
    /**
     * 保存一个对象到mongodb
     * 
     * @param bean
     * @return
     */
    public T save(T bean) {
        mongoTemplate.save(bean);
        return bean;
    }

    /**
     * 通过ID获取记录
     * 
     * @param id
     * @return
     */
    public T findById(String id) {
        return mongoTemplate.findById(id, this.entityClass);
    }

    /**
     * 通过ID获取记录,并且指定了集合名(表的意思)
     * 
     * @param id
     * @param collectionName
     *            集合名
     * @return
     */
    public T findById(String id, String collectionName) {
        return mongoTemplate.findById(id, this.entityClass, collectionName);
    }
    
    /**
     * remove
     * @param id
     */
    public void remove(Query query) {
        mongoTemplate.remove(query, entityClass);
    }
    
    /**
     * 保存全部
     * @param list
     * @return
     */
    public List<T> save(List<T> list) {
        mongoTemplate.insertAll(list);
        return list;
    }
}
View Code

 

3.编写AppCategoryDao

技术分享
import java.util.List;

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import com.cyou.nad.goldlocker.dao.base.MongoBaseDao;
import com.cyou.nad.goldlocker.domain.mongo.AppCategory;

/**
 * AppCategoryMongoDao 
 * 
 * @author yangkun
 * 
 */
@Repository
public class AppCategoryMongoDao extends MongoBaseDao<AppCategory> {

    @Override
    public  AppCategory  findById(String unique) {
        Query q = new Query(Criteria.where("_id").is(unique));
        System.out.print(super.findOne(q).getCategory());
        return super.findOne(q);
    }
    
    @Override
    public List<AppCategory> findAll() {
        Query q = new Query();
        return super.find(q);
    }
    
    @Override
    public AppCategory save(AppCategory app) {
        mongoTemplate.save(app);
        return app;
    }
    
    public void remove(String unique) {
        // TODO Auto-generated method stub
        Query q = new Query(Criteria.where("_id").is(unique));
        Update update = new Update();
        update.set("flag_off", 1);
        mongoTemplate.upsert(q, update, AppCategory.class);
    }
    
    public void remAndinser(AppCategory app) {
        // TODO Auto-generated method stub
        String _id = app.get_id();
        Query q = new Query(Criteria.where("_id").is(_id));
        
        Update update = new Update();
        update.set("category", app.getCategory());
        update.set("flag_off", app.getFlag_off());
        update.set("ctype", app.getCtype());
        update.set("aliases", app.getAliases());
        update.set("words", app.getWords());
        update.set("related", app.getRelated());
        
        mongoTemplate.updateMulti(q, update, AppCategory.class);
    }
    
}
View Code

 

4.编程中遇到的问题

  1.使用update进行更新,更新的代码为:

String _id = app.get_id();
Query q = new Query(Criteria.where("_id").is(_id));
Update update = new Update();
//这里将要更新的内容通过update对象的set方法设置进去,只需要按照字段即可,无需考虑字段类型。

 update.set("category", app.getCategory());
 update.set("flag_off", app.getFlag_off());
 update.set("ctype", app.getCtype());
 update.set("aliases", app.getAliases());
 update.set("words", app.getWords());
 update.set("related", app.getRelated());

mongoTemplate.updateMulti(q, update, AppCategory.class);  

方法解释:
  updateMulti:代表更新有相同条件的所有数据。
  updateFirst:代表只更新有相同条件的第一条数据。
参数解释:
  第一个参数:类似于SQL语句中的where条件。匹配你想更新的数据
  第二个参数:需要更新的内容。
  第三个参数:要更新的类的Class对象

  2.AppCategory获取id问题

技术分享
import java.util.List;

import org.springframework.data.mongodb.core.mapping.Document;

import com.cyou.nad.goldlocker.constant.MongoCollections;

/**
 * AppCategory
 * 
 * @author yangkun
 * 
 */
@Document(collection=MongoCollections.AppCategory)
public class AppCategory {
    
    private String _id;

    private int ctype;
    
    private String flag_off;
    
    private String category;
    
    private List<String> aliases;
    
    private List<String> words;
    
    private Related related;

    
    public int getCtype() {
        return ctype;
    }

    public void setCtype(int ctype) {
        this.ctype = ctype;
    }

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }
    
    public String getId() {
        return _id;
    }

    public void setId(String id) {
        this._id = id;
    }

    

    public String getFlag_off() {
        return flag_off;
    }

    public void setFlag_off(String flag_off) {
        this.flag_off = flag_off;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public List<String> getAliases() {
        return aliases;
    }

    public void setAliases(List<String> aliases) {
        this.aliases = aliases;
    }

    public List<String> getWords() {
        return words;
    }

    public void setWords(List<String> words) {
        this.words = words;
    }

    public Related getRelated() {
        return related;
    }

    public void setRelated(Related related) {
        this.related = related;
    }

    
}
View Code

  问题:这里需要根据Mongo自动生成的_id字段去更新内容,前台是通过JSON传递到Controller的,使用fastJson去解析JSON,但是解析出来的app类的_id总是不会被设置上值。导致无法通过_id被更新。

AppCategory app = JSONObject.parseObject(jsonStr, AppCategory.class);

  于是想到是不是因为AppCategory的_id属性名称的命名问题,导致反射的时候调用不到set方法导致的。于是创建一个新的字段命名为:id,提供get和set方法,在id的set方法中调用_id的set方法。然后问题解决。但是后续因为项目进度原因没有继续研究到底是不是fastJSON的问题,还是别的。不过在之后的pojo的命名方式提供了借鉴。

以上是关于MongoDB使用记录的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB PHP

Sphinx - 在代码块片段中使用省略号 (...)

记录C#常用的代码片段

详解MongoDB索引优化

discuz X3.1 源代码阅读,记录代码片段

mongodb关联查询