Spring Mongodb嵌套集合字段的分页

时间:2016-05-12 18:55:48

标签: java spring mongodb pagination spring-data-mongodb

我在另一个文档中有一个文档集合。想要在获取数据时对嵌套元素实现分页。你能告诉我怎么做吗?在结构中,我想使用分页来获取消息。

public abstract class CommonDomainAttributes implements Serializable, Cloneable {
    private static final long serialVersionUID = 1L;

    @Id
    protected String id;

    @JsonIgnore
    @CreatedDate
    protected Date createDate;

    //@JsonIgnore
    @LastModifiedDate
    //@JsonSerialize(using=JsonDateSerializer.class)
    protected Date lastModifiedDate;

    @JsonIgnore
    @CreatedBy
    protected String createdBy;

    @JsonIgnore
    @LastModifiedBy
    protected String lastModifiedBy;
    /**
     * @return the id
     */
    public String getId() {
        return id;
    }
    /**
     * @param id the id to set
     */
    public void setId(String id) {
        this.id = id;
    }
    /**
     * @return the createDate
     */
    public Date getCreateDate() {
        return createDate;
    }
    /**
     * @param createDate the createDate to set
     */
    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
    /**
     * @return the lastModifiedDate
     */
    public Date getLastModifiedDate() {
        return lastModifiedDate;
    }
    /**
     * @param lastModifiedDate the lastModifiedDate to set
     */
    public void setLastModifiedDate(Date lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }
    /**
     * @return the createdBy
     */
    public String getCreatedBy() {
        return createdBy;
    }
    /**
     * @param createdBy the createdBy to set
     */
    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }
    /**
     * @return the lastModifiedBy
     */
    public String getLastModifiedBy() {
        return lastModifiedBy;
    }
    /**
     * @param lastModifiedBy the lastModifiedBy to set
     */
    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (id == null ? 0 : id.hashCode());
        return result;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        CommonDomainAttributes other = (CommonDomainAttributes) obj;
        if (id == null) {
            if (other.id != null) {
                return false;
            }
        } else if (!id.equals(other.id)) {
            return false;
        }
        return true;
    }




    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("CommonDomainAttributes [id=").append(id)
        .append(", createDate=").append(createDate)
        .append(", lastModifiedDate=").append(lastModifiedDate)
        .append(", createdBy=").append(createdBy)
        .append(", lastModifiedBy=").append(lastModifiedBy)
        .append(", toString()=").append(super.toString()).append("]");
        return builder.toString();
    }


}

public class Message extends CommonDomainAttributes implements Serializable{

    private String fromuserId;
    private String fromuserName;
    private String toUserId;
    private String touserName;
    private String message;
    /**
     * @return the fromuserId
     */
    public String getFromuserId() {
        return fromuserId;
    }
    /**
     * @param fromuserId the fromuserId to set
     */
    public void setFromuserId(String fromuserId) {
        this.fromuserId = fromuserId;
    }
    /**
     * @return the fromuserName
     */
    public String getFromuserName() {
        return fromuserName;
    }
    /**
     * @param fromuserName the fromuserName to set
     */
    public void setFromuserName(String fromuserName) {
        this.fromuserName = fromuserName;
    }
    /**
     * @return the toUserId
     */
    public String getToUserId() {
        return toUserId;
    }
    /**
     * @param toUserId the toUserId to set
     */
    public void setToUserId(String toUserId) {
        this.toUserId = toUserId;
    }
    /**
     * @return the touserName
     */
    public String getTouserName() {
        return touserName;
    }
    /**
     * @param touserName the touserName to set
     */
    public void setTouserName(String touserName) {
        this.touserName = touserName;
    }
    /**
     * @return the message
     */
    public String getMessage() {
        return message;
    }
    /**
     * @param message the message to set
     */
    public void setMessage(String message) {
        this.message = message;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Message [fromuserId=");
        builder.append(fromuserId);
        builder.append(", fromuserName=");
        builder.append(fromuserName);
        builder.append(", toUserId=");
        builder.append(toUserId);
        builder.append(", touserName=");
        builder.append(touserName);
        builder.append(", message=");
        builder.append(message);
        builder.append(", toString()=");
        builder.append(super.toString());
        builder.append("]");
        return builder.toString();
    }
}

@Document(collection="discussion")
@TypeAlias("discussion")
public class Discussion extends CommonDomainAttributes implements Serializable{

    private String discussionTopic;
    private List<Message> messages;
    /**
     * @return the discussionTopic
     */
    public String getDiscussionTopic() {
        return discussionTopic;
    }
    /**
     * @param discussionTopic the discussionTopic to set
     */
    public void setDiscussionTopic(String discussionTopic) {
        this.discussionTopic = discussionTopic;
    }
    /**
     * @return the messages
     */
    public List<Message> getMessages() {
        return messages;
    }
    /**
     * @param messages the messages to set
     */
    public void setMessages(List<Message> messages) {
        this.messages = messages;
    }


    /**
     * @param messages the messages to set
     */
    public void addMessages(Message message) {
        if(null == messages){
            messages = new LinkedList<>();
        }
        messages.add(message);
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Discussion [discussionTopic=");
        builder.append(discussionTopic);
        builder.append(", messages=");
        builder.append(messages);
        builder.append(", toString()=");
        builder.append(super.toString());
        builder.append("]");
        return builder.toString();
    }

}

1 个答案:

答案 0 :(得分:4)

关于Mongo查询语言的一点

在MongoDB中,$slice运算符控制查询返回的数组的项数。 $slice运算符可以使用以下语法接受值:

[toSkip, toLimit]

其中第一个值表示要跳过的数组中的项数,第二个值表示要返回的项数。例如,您可以使用以下查询:

db.discussions.find({}, {messages: {$slice: [20, 10]}})

在跳过该阵列的前20条消息后返回10条消息。

将其带入Spring Data World

为了在Spring Data MongoDB中使用$slice运算符,您应该使用@Query注释及其fields属性。例如,如果您有DiscussionRepository,则可以编写如下内容:

public interface DiscussionRepository extends MongoRepository<Discussion, String> {
    @Query(value = "{}", fields = "{messages: {$slice: [?0, ?1]}}")
    List<Discussion> findDiscussions(int skip, int limit);
}

通过这种安排,以下方法调用:

discussionRepository.findDiscussions(20, 10)

会产生与:

相同的结果
db.discussions.find({}, {messages: {$slice: [20, 10]}})

通过一些工作,您可以将Skip/Limit组合转换为分页功能。