#
MONGODB中,由于删除大量记录会十分耗时,一般推荐由MONGODB自己在后台处理,只需在某个字段设一个索引的标签即可。
@Indexed(expireAfterSeconds=180)
private Date deletedAt;
以上代码,如果字段deletedAt有值,那么将在180秒后被MONGODB删除,如果没值不会被删除。批量新增,小批量更新,防止读取超时
private <T> void insertAll(List<T> list) {
if (null != list) {
int total = list.size();
int count = (total + 50000 -1) / 50000;
for (int i = 0; i < count; i++) {
int toIndex = ((i +1) * 50000 > total) ? total : ((i +1) * 50000);
log.info("toIndex = " + toIndex);
mongoTemplate1.insertAll(list.subList(i * 50000, toIndex));
}
}
}
批量更改
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
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 com.tcl.project7.boss.gameapplication.yearendactivities.bigwheelgame.valueobject.SingleUseRedeemCode;
public class SingleUseRedeemCodeRepositoryImpl implements SingleUseRedeemCodeRepositoryCustom{
@Autowired
private MongoTemplate mongoTemplate1;
public void batchUpdateSingleUseRedeemCodeList(String bigWheelGameAwardId) {
Query query = new Query();
query.addCriteria(Criteria.where("bigwheelgameawardid").is(bigWheelGameAwardId));
mongoTemplate1.updateMulti(
query,
new Update().set("bigwheelgameawardid", "-1")
.set("deletedat", new Date()),
SingleUseRedeemCode.class);
}
}
Expire Data from Collections by Setting TTL¶
This document provides an introduction to MongoDB’s “time to live” or TTL collection feature. TTL collections make it possible to store data in MongoDB and have the mongod automatically remove data after a specified number of seconds or at a specific clock time.
Data expiration is useful for some classes of information, including machine generated event data, logs, and session information that only need to persist for a limited period of time.
A special TTL index property supports the implementation of TTL collections. The TTL feature relies on a background thread in mongod that reads the date-typed values in the index and removes expired documentsfrom the collection.
Procedures
To create a TTL index, use the db.collection.createIndex() method with theexpireAfterSeconds option on a field whose value is either a date or an array that contains date values.
NOTE
The TTL index is a single field index. Compound indexes do not support the TTL property. For more information on TTL indexes, see TTL Indexes.
Expire Documents after a Specified Number of Seconds
To expire data after a specified number of seconds has passed since the indexed field, create a TTL index on a field that holds values of BSON date type or an array of BSON date-typed objects and specify a positive non-zero value in the expireAfterSeconds field. A document will expire when the number of seconds in the expireAfterSeconds field has passed since the time specified in its indexed field. [1]
For example, the following operation creates an index on the log_events collection’s createdAt field and specifies the expireAfterSeconds value of 3600 to set the expiration time to be one hour after the time specified by createdAt.
db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
When adding documents to the log_events collection, set the createdAt field to the current time:
db.log_events.insert( { "createdAt": new Date(), "logEvent": 2, "logMessage": "Success!" } )
MongoDB will automatically delete documents from the log_events collection when the document’screatedAt value [1] is older than the number of seconds specified in expireAfterSeconds.
[1] | (1, 2) If the field contains an array of BSON date-typed objects, data expires if at least one of BSON date-typed object is older than the number of seconds specified in expireAfterSeconds. |
Expire Documents at a Specific Clock Time
To expire documents at a specific clock time, begin by creating a TTL index on a field that holds values of BSON date type or an array of BSON date-typed objects and specify an expireAfterSeconds value of0. For each document in the collection, set the indexed date field to a value corresponding to the time the document should expire. If the indexed date field contains a date in the past, MongoDB considers the document expired.
For example, the following operation creates an index on the log_events collection’s expireAt field and specifies the expireAfterSeconds value of 0:
db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
For each document, set the value of expireAt to correspond to the time the document should expire. For instance, the following insert() operation adds a document that should expire at July 22, 201314:00:00.
db.log_events.insert( { "expireAt": new Date('July 22, 2013 14:00:00'), "logEvent": 2, "logMessage": "Success!" } )
MongoDB will automatically delete documents from the log_events collection when the documents’expireAt value is older than the number of seconds specified in expireAfterSeconds, i.e. 0 seconds older in this case. As such, the data expires at the specified expireAt value.
We have a db collection that is around 30 million documents, and I need to trim it down, to only keeping the documents created on the last month.
One approach would be use the remove
command with a condition on the created_at
field (the collection already have an index on this field):
db.my_collection.remove({created_at: {$lte: new Date("11/01/2012")}});
But this approach will be very slow, instead of that, a better way to do it is rename the current collection (for instance to “old_collection”) using renameCollection
. Then performing a query-and-insert from the “old_collection” into “my_collection”:
db.my_collection.renameCollection("old_collection");
db.createCollection("my_collection");
db.my_collection.createIndex(...); // recreate the indexes for the collection
// copy docs from old collection into the new collection
db.old_collection.find(
{created_at: {$gte: new Date("11/01/2012")}} ).sort({_id: -1}).forEach(
function(row) { db.my_collection.insert(row); } ); // drop old collection db.old_collection.drop();
This approach is typically faster than running a bunch of removes on your data
MongoDB 固定集合(Capped Collections)是性能出色且有着固定大小的集合,对于大小固定,我们可以想象其就像一个环形队列,当集合空间用完后,再插入的元素就会覆盖最初始的头部的元素!
创建固定集合
我们通过createCollection来创建一个固定集合,且capped选项设置为true:
>db.createCollection("cappedLogCollection",{capped:true,size:10000})
还可以指定文档个数,加上max:1000属性:
>db.createCollection("cappedLogCollection",{capped:true,size:10000,max:1000})
判断集合是否为固定集合:
>db.cappedLogCollection.isCapped()
如果需要将已存在的集合转换为固定集合可以使用以下命令:
>db.runCommand({"convertToCapped":"posts",size:10000})
以上代码将我们已存在的 posts 集合转换为固定集合。
固定集合查询
固定集合文档按照插入顺序储存的,默认情况下查询就是按照插入顺序返回的,也可以使用$natural调整返回顺序。
>db.cappedLogCollection.find().sort({$natural:-1})
固定集合的功能特点
可以插入及更新,但更新不能超出collection的大小,否则更新失败,不允许删除,但是可以调用drop()删除集合中的所有行,但是drop后需要显式地重建集合。
在32位机子上一个cappped collection的最大值约为482.5M,64位上只受系统文件大小的限制。
固定集合属性及用法
属性
- 属性1:对固定集合进行插入速度极快
- 属性2:按照插入顺序的查询输出速度极快
- 属性3:能够在插入最新数据时,淘汰最早的数据
用法
http://www.runoob.com/mongodb/mongodb-aggregate.html
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。
aggregate() 方法
MongoDB中聚合的方法使用aggregate()。
语法
aggregate() 方法的基本语法格式如下所示:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
实例
集合中的数据如下:
{ _id: ObjectId(7df78ad8902c) title: 'MongoDB Overview', description: 'MongoDB is no sql database', by_user: 'w3cschool.cc', url: 'http://www.w3cschool.cc', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 }, { _id: ObjectId(7df78ad8902d) title: 'NoSQL Overview', description: 'No sql database is very fast', by_user: 'w3cschool.cc', url: 'http://www.w3cschool.cc', tags: ['mongodb', 'database', 'NoSQL'], likes: 10 }, { _id: ObjectId(7df78ad8902e) title: 'Neo4j Overview', description: 'Neo4j is no sql database', by_user: 'Neo4j', url: 'http://www.neo4j.com', tags: ['neo4j', 'database', 'NoSQL'], likes: 750 },
现在我们通过以上集合计算每个作者所写的文章数,使用aggregate()计算结果如下:
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]) { "result" : [ { "_id" : "w3cschool.cc", "num_tutorial" : 2 }, { "_id" : "Neo4j", "num_tutorial" : 1 } ], "ok" : 1 } >
以上实例类似sql语句: select by_user, count(*) from mycol group by by_user
在上面的例子中,我们通过字段by_user字段对数据进行分组,并计算by_user字段相同值的总和。
下表展示了一些聚合的表达式:
表达式 | 描述 | 实例 |
---|
$sum | 计算总和。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
$avg | 计算平均值 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min | 获取集合中所有文档对应值得最小值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max | 获取集合中所有文档对应值得最大值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push | 在结果文档中插入值到一个数组中。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | 根据资源文档的排序获取第一个文档数据。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
管道的概念
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
- $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
- $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
- $limit:用来限制MongoDB聚合管道返回的文档数。
- $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
- $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
- $group:将集合中的文档分组,可用于统计结果。
- $sort:将输入文档排序后输出。
- $geoNear:输出接近某一地理位置的有序文档。
管道操作符实例
1、$project实例
db.article.aggregate( { $project : { title : 1 , author : 1 , }} );
这样的话结果中就只还有_id,tilte和author三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:
db.article.aggregate( { $project : { _id : 0 , title : 1 , author : 1 }});
2.$match实例
db.articles.aggregate( [ { $match : { score : { $gt : 70, $lte : 90 } } }, { $group: { _id: null, count: { $sum: 1 } } } ] );
$match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。
3.$skip实例
db.article.aggregate( { $skip : 5 });
经过$skip管道操作符处理后,前五个文档被"过滤"掉。
摘要: 在这篇文章中,我将告诉大家我对hashCode和equals方法的理解。我将讨论他们的默认实现,以及如何正确的重写他们。我也将使用Apache Commons提供的工具包做一个实现。 目录:hashCode()和equals()的用法重写默认实现使用Apache Commons Lang包重写hashCode()和equals()需要注意记住的事情当使用ORM的时候特别要注意的hashC...
阅读全文
双清教程:
- 手机关机,按住音量上+HOME+电源键
- 选择 wipe date/factory reset
- 选择 yes dalete all user data
- 选择 wipe cache partition
- 选择 yes wipe cache
如何医治牙龈出血啊。。。谢谢啊,狂急!!!!
悬赏分:0 - 解决时间:2005-11-22 12:37
提问者: 小哈纳斯 - 魔法学徒 一级
http://www.234.com.tw/perio/topicList.cfm?kid=61
最佳答案
这里是我以前答复两个患者的资料,对你有作用:
一 关于青年人牙龈出血
⑴ 我想你是牙龈出血。若是其它原因出血,你肯定早住医院而不会在这里轻松发贴了。
⑵ 这个臭味是来自血的腐败。既然牙龈会出血,也表明你有牙周的问题,这些渗血部位的牙垢及食物残渣也会发出难闻的气味。
⑶ 治疗一般应到专门的口腔门诊。看来你是第一次涉及口腔的保健,治疗的流程应该是这样的:
先消除炎症:常规是口服利菌沙,灭滴灵,维生素C,维生素K。治疗约1周后,牙龈炎症消除,就应着手解决根本问题了。
再清除牙垢:这是引起牙周炎的原因。牙垢很硬,堆积在牙龈周围,不断地刺激和损伤着牙龈,使成创面出血。而出血又可进一步形成牙垢,如此成恶性循环。
⑷ 在我们三甲医院,这个费用偏高些,约100元。它包括消炎和约两次的除垢(洗牙)。在县市级的医院应该便宜些。
⑸ 消炎7天加除垢2天。若同时治疗龋齿,还加2天。
⑹ 当然,你也可只做消炎一步,除垢待以后有时间再做。如此,你到大的药房去,买前3种药自己服。买3-5天的量。约花20元。
⑹ 这3-5天内,你要睡眠良好,尽量避免感冒发热,那会引起血管通透性趋增,使出血严重一些,不利于治疗消炎。
⑺ 平时多食富含维生素C的水果蔬菜很重要!!!
好,暂就说这么多。对顽固性的牙龈出血(例如出了多年血),或是这样治疗仍不见效,请再设问,我们来为你确定新的治疗方案。
二 关于老是治不好的牙龈出血(先用一法!!!!)
楼上解释的对。但我要教你最重要的东西,就是怎样解决这个问题。当然,解决之后,你要补我的专家号,呵呵。(我有个熟人有40年牙龈出血的经历,可是它近年突然好了。你想知道原因吗?我给了他一个新招。)
⑴ 连服维生素C7天,每天100-300mg。(这个量不算多,意义你明白。)
⑵ 这7天内保持好睡眠,目的是调节好人的生理状态,使不容易感冒什么的,避免因发烧造成的微血管通透性能趋增,使容易出血。
⑶ 本条最重要:去药房买“阿奇霉素分散片”,买大厂出的,我建议买天津药业悦来牌的。每盒6片×0.25g,请单次口服4片,并详细阅读一下说明书。记住:只吃一次即可。若有严重的不良反应(极少有!!),带着这个药的说明书去看门诊,医生会处置。如果没有不良反应,可在48小时后把另2片吃了,仅此而已。
该药是目前极有名的药,4年前从国外进来现已完全本土化,真的是国外科学家对人类的大贡献!也不算贵,约20-30元1盒6片。主要用途是对付非淋菌性性病。
它是广谱抗菌药,更是☆靶向制剂☆。你明白这个吗?我说个白话以便你能听懂:这个药可跟随人的巨嗜细胞走。而巨嗜细胞又跟着炎症走,所以疗效显著。
⑷ 一般的牙科医生,都会建议你用利君沙和灭滴灵,外加维生素C和K。但我想你是老牙龈出血,这种药用过多次,不会太奏效,阿奇霉素毒副作用比上述两种都小,更重要的是你没用过,致病菌没有抗药性。
⑸ 炎症消除、出血停止之后,建议你去做一次牙垢清除。多年的出血肯定会导致牙根周围有比较多的牙垢,这些牙垢年复一年刺激着周围的牙龈,不但是细菌的温床,也使牙龈面持续受到创伤,牙龈出血还会卷土重来。
⑹ 此次牙龈炎症消除之后,口腔气味也会比以前好转,但牙根的一部分将暴露的比以前利害(以前被肿胀的牙龈包裹),产生龋齿的可能性将增加。因此要注意好口腔清洁。
回答者: ccd2093 - 举人 四级 11-14 08:51
提问者对于答案的评价:
非常感谢~~
如果用RSA加密数据的话,会有数据长度的要求,否则会抛异常:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
推荐的做法:
- 随机生成一个密钥,用作对称密钥UUID
- 用此对称密钥,用对称加密法AES加密数据
- 用RSA的公钥加密此对称密钥
- 发送加密后的对称密钥和加密数据
- 用RSA私钥解密加密后的对称密钥
- 用解密密后的对称密钥,解密数据
- 完成
AESSecurityUtil.java
import java.security.Key;
import java.util.UUID;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AESSecurityUtil {
// 加密算法
/** 指定加密算法为RSA */
private static final String ALGORITHM = "AES";
// 加密密钥
// private static final byte[] keyValue = new byte[] { 'T', 'h', 'e',
// 'B','e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };
// 16位的加密密钥
// private byte[] keyValue;
/**
* 用来进行加密的操作
*
* @param Data
* @return
* @throws Exception
*/
public static String encrypt(String keyString, String data)
throws Exception {
Key key = generateKey(keyString);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(data.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}
/**
* 用来进行解密的操作
*
* @param encryptedData
* @return
* @throws Exception
*/
public static String decrypt(String keyString, String encryptedData) throws Exception {
Key key = generateKey(keyString);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
public static String generateKeyString()
{
//必须长度为16
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
}
/**
* 根据密钥和算法生成Key
*
* @return
* @throws Exception
*/
private static Key generateKey(String keyString) throws Exception {
Key key = new SecretKeySpec(keyString.getBytes(), ALGORITHM);
return key;
}
public static void main(String [] args) throws Exception
{
String keyString = generateKeyString();
// String keyString = "1234567890123456";
System.out.println("密钥:" + keyString);
String source = "恭喜发财!";// 要加密的字符串
System.out.println("准备用密钥加密的字符串为:" + source);
String cryptograph = encrypt(keyString, source);// 生成的密文
System.out.print("用密钥加密后的结果为:" + cryptograph);
System.out.println();
String target = decrypt(keyString, cryptograph);// 解密密文
System.out.println("用密钥解密后的字符串为:" + target);
System.out.println();
}
}
CryptoUtil.java
import com.tcl.project7.boss.common.crypto.CryptoData;
import com.tcl.project7.boss.common.util.JsonManager;
import com.tcl.project7.boss.common.util.file.FileUtil;
import com.tcl.project7.boss.gameapplication.yearendactivities.bigwheelgame.player.valueobject.BigWheelGameRequest;
public class CryptoUtil {
public static CryptoData encrypt(String data) throws Exception
{
//1、产生AES密钥
String keyString = AESSecurityUtil.generateKeyString();
//2、用AES法加密数据
String cryptograph = AESSecurityUtil.encrypt(keyString, data);
//3、用RSA加密AES密钥
String finalKey = RSASecurityUtil.encrypt(keyString);
// System.out.print("用RSA加密AES密钥为:" + finalKey);
// System.out.print("加密数据:" + cryptograph);
CryptoData cryptoData = new CryptoData();
cryptoData.setKey(finalKey);
cryptoData.setContent(cryptograph);
//4、返回数据
return cryptoData;
}
public static String decrypt(String keyString, String data) throws Exception
{
//1、解密密钥
String decryptKeyString = RSASecurityUtil.decrypt(keyString);
//2、解密内容
String decryptData = AESSecurityUtil.decrypt(decryptKeyString, data);
//3、返回
return decryptData;
}
public static void main(String [] args) throws Exception
{
String aFilePath = "DATA/TESTING-FILE/TOCRYPTO/tocrypto.txt";
String source = FileUtil.getContents(aFilePath);
CryptoData cryptoData = encrypt(source);
System.out.print(cryptoData);
String target = decrypt(cryptoData.getKey(), cryptoData.getContent());
System.out.print(target);
BigWheelGameRequest bigWheelGameRequest = JsonManager.getBean(target, BigWheelGameRequest.class);
System.out.print(bigWheelGameRequest);
}
}
CryptoData.java
import java.io.Serializable;
public class CryptoData implements Serializable{
private static final long serialVersionUID = -4774469372648172844L;
private String key;
private String content;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String toString() {
return "CryptoData [key=" + key + ", content=" + content + "]";
}
}
import java.io.IOException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ColumnControllerTest {
private Logger logger = LoggerFactory.getLogger(ColumnControllerTest.class);
@Test
public void testTest()
{
ObjectMapper mapper = new ObjectMapper();
/*AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
// make deserializer use JAXB annotations (only)
mapper.getDeserializationConfig().setAnnotationIntrospector(introspector);
// make serializer use JAXB annotations (only)
mapper.getSerializationConfig().setAnnotationIntrospector(introspector);*/
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
String userStr = "{\"username\":\"paul\",\"email\":\"paul@paul.com\"}";
try {
TypeReference<TestUser> temp = new TypeReference<TestUser>(){};
TestUser testUser = mapper.readValue(userStr, temp);
System.out.println(testUser.toString());
String result = mapper.writeValueAsString(testUser);
System.out.println(result);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
摘要: ice-dubbo-thrift-grpc性能测试对比,本次测试过程中还发现了一个支付宝的秘密,附件文档中会详细说明。测试说明 本测试只是个人为了对rpc进行技术选型,测试可能不够严谨,对某些rpc的参数可能也不是最优,如果你知道更优的参数配置或者改进意见等,欢迎反馈给我magicdoom@gmail.com。另外代码有些地方只是为了测试方便,不作为平时编程的范例。所有测...
阅读全文