MongoDB操作
<h4>重要的事情说三遍:如果你的业务需要复杂的查询语句,MongoDB是非结构型数据库,不要用!不要用!不要用!不然后面坑死你!能用MySQL、Oracle千万不要用它,复杂查询的资料网上很难找到。</h4><h4>一、MongoDB的DML语句</h4>
<p>在发布生产云服务器的时候,经常会出现导入脚本报错。以阿里云的MongoDB为例,目前只支持.csv,且导入经常失败,此时需要DML语句。</p>
<h4>insert()方法:</h4>
<p>下面是在inventory集合中插入一个三个字段的文档:</p>
<div class="cnblogs_code">
<pre>db.inventory.insert( { _id: 10, type: "misc", item: "card", qty: 15 } )</pre>
</div>
<h4>save()方法:</h4>
<p>使用save()方法插入一个文档,通过该方法保存一个不包含_id字段的文档或者包含_id字段但该字段值不存在集合中的文档。下面的示例创建一个新的文档在inventory集合:</p>
<div class="cnblogs_code">
<pre>db.inventory.save( { type: "book", item: "notebook", qty: 40 } )</pre>
</div>
<p>当在使用save方法时,插入不指定_id时,会自动生成一个。</p>
<p>Insert和Save的区别是:如果插入的集合的“_id”值,在集合中已经存在,用Insert执行插入操作会报异常,已经存在"_id"的键。用Save如果系统中没有相同的"_id"就执行插入操作,有的话就执行覆盖掉原来的值。相当于修改操作。</p>
<h4>update()方法:</h4>
<p>调用update()方法使用upsert标志创建一个新文档当没有匹配查询条件的文档时。下面的例子当inventory集合中没有包含{type:"books",item:"journal"}的文档时创建一个新文档:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">db.s_city.update(
{
cityName : </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">深圳</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
},
{
$</span><span style="color: rgba(0, 0, 255, 1)">set</span>: {cityName:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">深圳市</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}
});</span></pre>
</div>
<p> </p>
<h4>二、Criteria操作MongoDB</h4>
<p>基于:org.springframework.data.mongodb.core.query</p>
<h5>简单查询</h5>
<div class="cnblogs_code">
<pre>public List<Msg> getUserVideo(int userId) {<br> Query query = createQuery("userId",userId);<br> addToQuery(query, "body.type", 4);<br> return queryListsByQuery(query);<br>}</pre>
</div>
<h5>查询返回一个字段</h5>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">public</span> List<ObjectId><span style="color: rgba(0, 0, 0, 1)"> getPraiseIds(Integer userId) {
Query query </span>= createQuery(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">userId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, userId);
List</span><ObjectId> msgIds = getDatastore().findDistinct(query, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">msgId</span><span style="color: rgba(128, 0, 0, 1)">"</span>, Praise.<span style="color: rgba(0, 0, 255, 1)">class</span>, ObjectId.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> msgIds;
}</span></pre>
</div>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">public</span> List<Integer> queryBlacklistUserId(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> userId) {
Query query </span>= createQuery(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">userId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, userId);
addToQuery(query, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">blacklist</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> distinct(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">toUserId</span><span style="color: rgba(128, 0, 0, 1)">"</span>, query, Integer.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
}</span></pre>
</div>
<h5>in查询</h5>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">long</span> getPraiseCountByMsg(List<String><span style="color: rgba(0, 0, 0, 1)"> msgId) {
Query query </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Query();
query.addCriteria(Criteria.</span><span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">msgId</span><span style="color: rgba(128, 0, 0, 1)">"</span>).<span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)">(msgId));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> count(query);
}</span></pre>
</div>
<h5>去除</h5>
<div class="cnblogs_code">
<pre>query.addCriteria(Criteria.<span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">customer</span><span style="color: rgba(128, 0, 0, 1)">"</span>).ne(<span style="color: rgba(128, 0, 128, 1)">1</span>)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">去掉客服群</span></pre>
</div>
<h5>or查询</h5>
<div class="cnblogs_code">
<pre>query.addCriteria(new Criteria().orOperator(Criteria.where("manualPay_status").is(2),<br> new Criteria().andOperator(Criteria.where("status").is(1)<br> )));</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">query.addCriteria(
</span><span style="color: rgba(0, 0, 255, 1)">new</span> Criteria().orOperator(Criteria.<span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nickname</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).regex(keyWord),
Criteria.</span><span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">telephone</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).regex(keyWord),
Criteria.</span><span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">account</span><span style="color: rgba(128, 0, 0, 1)">"</span>).regex(keyWord)));</pre>
</div>
<h5>修改</h5>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> updateByCommentId(ObjectId commentId, Map<String, Object><span style="color: rgba(0, 0, 0, 1)"> map) {
Query query </span>= createQuery(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">commentId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, commentId);
Update ops </span>=<span style="color: rgba(0, 0, 0, 1)"> createUpdate();
map.forEach((key, value) </span>-><span style="color: rgba(0, 0, 0, 1)"> {
ops.</span><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">(key, value);
});
update(query, ops);
}</span></pre>
</div>
<h5>模糊查询</h5>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(0, 0, 255, 1)">null</span> !=<span style="color: rgba(0, 0, 0, 1)"> nickName){
query.addCriteria(Criteria.</span><span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nickName</span><span style="color: rgba(128, 0, 0, 1)">"</span>).regex(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">.*</span><span style="color: rgba(128, 0, 0, 1)">"</span> + nickName + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">.*</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">));
}</span></pre>
</div>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">StringUtil.isEmpty(roomName)) {
query.addCriteria(containsIgnoreCase(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, roomName));
}</span></pre>
</div>
<h5>删除</h5>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> deleteMsg(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> userId) {
Query query </span>= createQuery(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">userId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, userId);
deleteByQuery(query);
}</span></pre>
</div>
<h5>聚合分页 </h5>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* 按时间区间统计每个用户看广告的收益
* @param beginTime 开始时间
* @param endTime 结束时间
* @param pageIndex页码(必须分页处理,海量数据)
* @param pageSize
* @return
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> List<WatchAdvertising> getTotalMoney(<span style="color: rgba(0, 0, 255, 1)">long</span> beginTime, <span style="color: rgba(0, 0, 255, 1)">long</span> endTime, <span style="color: rgba(0, 0, 255, 1)">int</span> pageIndex, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> pageSize) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">封装查询条件</span>
List<AggregationOperation> operations = <span style="color: rgba(0, 0, 255, 1)">new</span> ArrayList<><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(beginTime > <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">) {
operations.add(Aggregation.match(Criteria.</span><span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">time</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).gte(beginTime)));
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(endTime > <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">) {
operations.add(Aggregation.match(Criteria.</span><span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">time</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).lte(endTime)));
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">totalMoney为WatchAdvertising类中新建的属性,用于接收统计后的总收益;当然也可以使用money(或其他属性)接收,后面的 first("userId").as("userId") 代表需要查询的字段映射到实体里的名称</span>
operations.add(Aggregation.group(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">userId</span><span style="color: rgba(128, 0, 0, 1)">"</span>).first(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">userId</span><span style="color: rgba(128, 0, 0, 1)">"</span>).<span style="color: rgba(0, 0, 255, 1)">as</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">userId</span><span style="color: rgba(128, 0, 0, 1)">"</span>).sum(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">money</span><span style="color: rgba(128, 0, 0, 1)">"</span>).<span style="color: rgba(0, 0, 255, 1)">as</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">totalMoney</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">));
operations.add(Aggregation.project(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">userId</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">totalMoney</span><span style="color: rgba(128, 0, 0, 1)">"</span>).andExclude(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span>)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">去掉id</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> startRows = (pageIndex - <span style="color: rgba(128, 0, 128, 1)">1</span>) * pageSize;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">计算起始下标</span>
startRows = startRows < <span style="color: rgba(128, 0, 128, 1)">0</span> ? <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> : startRows;
operations.add(Aggregation.skip((</span><span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)">) startRows));
operations.add(Aggregation.limit((</span><span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)">) pageSize));
Aggregation aggregation </span>=<span style="color: rgba(0, 0, 0, 1)"> Aggregation.newAggregation(operations);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">查询、并获取结果</span>
AggregationResults<WatchAdvertising> results = mongoTemplate.aggregate(aggregation, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">watchAdvertising</span><span style="color: rgba(128, 0, 0, 1)">"</span>, WatchAdvertising.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> results.getMappedResults();
}</span></pre>
</div>
<h5> 分组去重</h5>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查询条件</span>
Criteria criteria =<span style="color: rgba(0, 0, 0, 1)"> Criteria
.</span><span style="color: rgba(0, 0, 255, 1)">where</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">logsType</span><span style="color: rgba(128, 0, 0, 1)">"</span>).<span style="color: rgba(0, 0, 255, 1)">is</span><span style="color: rgba(0, 0, 0, 1)">("LOGIN");
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 格式化日期 YY-MM-DD,并且指定时区,Mongo不区分时区,按月则%Y-%m</span>
AggregationExpression dateExpression =<span style="color: rgba(0, 0, 0, 1)"> DateOperators.DateToString
.dateOf(</span><span style="color: rgba(128, 0, 0, 1)">"createTime</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
.toString(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%Y-%m-%d</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
.withTimezone(
DateOperators.Timezone.valueOf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">+08</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
);
Aggregation aggregation </span>=<span style="color: rgba(0, 0, 0, 1)"> Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.project(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">account</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
.and(dateExpression).</span><span style="color: rgba(0, 0, 255, 1)">as</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">date</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">),
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 按日期和用户分组,去重用户,一个用户,一天只算一次</span>
Aggregation.group(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">date</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">account</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
.first(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">date</span><span style="color: rgba(128, 0, 0, 1)">"</span>).<span style="color: rgba(0, 0, 255, 1)">as</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">date</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
.first(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">account</span><span style="color: rgba(128, 0, 0, 1)">"</span>).<span style="color: rgba(0, 0, 255, 1)">as</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">account</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">),
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 统计按日期分组,统计每天登录的成功的总人数</span>
Aggregation.group(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">date</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
.count().</span><span style="color: rgba(0, 0, 255, 1)">as</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">loginUserNumber</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
.first(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">date</span><span style="color: rgba(128, 0, 0, 1)">"</span>).<span style="color: rgba(0, 0, 255, 1)">as</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">date</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
);
List</span><JSONObject> list = mongoTemplate.aggregate(aggregation, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">USER_LOGIN_RECORD</span><span style="color: rgba(128, 0, 0, 1)">"</span>, JSONObject.<span style="color: rgba(0, 0, 255, 1)">class</span>).getMappedResults();</pre>
</div>
<p> </p>
<p> </p>
<p>其他操作参考《MongoDB--Spring Data MongoDB详细的操作手册》</p>
<p>原生查询语句 mongodb 条件查询</p>
<p>事务 MongoDB与SpringBoot整合(支持事务)</p>
<p>多文档事务 </p><br><br>
来源:https://www.cnblogs.com/zeussbook/p/15003672.html
頁:
[1]