Leyou Mall (17) -- Comment service

MongoDB learning notes

1, Introduction to MongoDB

1.1 analysis on characteristics of comment data

The two functions of comment have the following characteristics:

  • Large amount of data
  • Frequent write operations
  • Low value

For such data, MongoDB is more suitable for data storage

1.2. What is MongonDB

The official website address of MongoDB is: https://www.mongodb.com/

MongoDB is a cross platform and document oriented database. It is the most popular NoSQL database product at present. It is between relational database and non relational database. It is the product with the most abundant functions and most like relational database among non relational databases. The data structure it supports is very loose. It is a JSON like BSON format, so it can store more complex data types

1.3 MongonDB features

The biggest feature of MongoDB is that the query language it supports is very powerful. Its syntax is a bit similar to the object-oriented query language. It can almost realize most functions similar to single table query of relational database, and also supports indexing of data. It is a collection oriented, schema free document database. The specific features are summarized as follows:

  1. For collection storage, it is easy to store object type data
  2. Mode freedom
  3. Support dynamic query
  4. Supports full indexing, including internal objects
  5. Support replication and failover
  6. Use efficient binary data storage, including large objects (such as video, etc.)
  7. Automatically process fragments to support the scalability of cloud computing hierarchy
  8. It supports the drivers of Python, PHP, Ruby, Java, C, c#, Javascript, Perl and C + + languages. The community also provides drivers for Erlang and. NET platforms
  9. The file storage format is BSON (an extension of JSON)

1.4 MongonDB architecture

The logical structure of MongoDB is a hierarchical structure. It is mainly composed of three parts: document, collection and database. The logical structure is user oriented. Users use MongoDB to develop applications.

  1. A MongoDB document is equivalent to a row of records in a relational database.
  2. Multiple documents form a collection, which is equivalent to a table in a relational database.
  3. Multiple collection s, logically organized together, are database s.
  4. A MongoDB instance supports multiple database s.

The hierarchy of document, collection and database is as follows:

Comparison of logical structure concepts between MongoDB and MySQL databases:

MongoDBMySQL
databasedatabase
collectionstable
documentrow

1.5 data type

typeexplain
Basic data type nullUsed to represent null or nonexistent fields, {x ': null}
BooleanBoolean types have two values, true and false, {x ': true}
numerical valueThe shell uses 64 as a floating-point value by default{“ x ": 3.14} or {x": 3}. For integer values, you can use NumberInt(4-byte signed integer) or NumberLong(8-byte signed integer), {"x": NumberInt("3")} {"x": NumberLong("3")}
character stringUTF-8 strings can be expressed as string type data, {x ":" hehe "}
dateThe date is stored as the number of milliseconds since the new era dependency. The time zone is not stored, {x ": new Date()}
regular expression When querying, regular expressions are used as qualifying conditions. The syntax is the same as that of regular expressions in JavaScript, {"x": / [abc] /}
arrayA data list or dataset can be represented as an array, {x ": [" a "," b "," c "]}
Embedded documentDocuments can be nested with other documents. The nested documents are treated as values, {x ": {y": 3}}
Object IdThe object id is a 12 byte string, which is the unique identification of the document, {x ": objectId()}
binary dataBinary data is an arbitrary byte string. It cannot be used directly in the shell. Binary data is the only way to save non utf- characters to the database.
codeQueries and documents can include any JavaScript code, {x ": function() {/... /}}

2, MongoDB installation and command

2.1 installation and startup

Download address: https://www.mongodb.com/try/download/community

Here, upload the compressed package to the / usr/local/leyou directory

#Here I choose the link to download
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.15.tgz
# Unzip the mongodb installation package
tar -zxvf mongodb-linux-x86_64-rhel70-4.2.15.tgz
#rename
mv mongodb-linux-x86_64-rhel70-4.2.15 mongodb
#Enter mongodb and create the data and logs directories
cd mongodb
mkdir data
mkdir logs

Start mongo

./mongod --dbpath=/usr/local/leyou/mongodb/data --logpath=/usr/local/leyou/mongodb/logs/mongod.log --logappend  --port=27017 --bind_ip=0.0.0.0 --fork

View log:

If these contents appear, it means that the startup is successful and port 27017 of Alibaba cloud security group is opened

2.2 common commands

2.2.1. Creating and selecting databases

Syntax format:

use database

use commentdb

If the database does not exist, the database is automatically created:

2.2.2. Inserting and querying documents

Insert syntax format:

db.Set name.insert(data)

db.commentdb.insert({userId:"001",nickName:"Mr.Wang",content:"Come on"})

Query all document formats:

db.Set name.find()

db.commentdb.find()

You will find that each document has a name called_ id field, which is equivalent to the primary key of the table in the relational database. If this field is not specified when inserting a document record, MongoDB will automatically create it, and its type is ObjectID. If this field is specified when inserting a document record, its type is ObjectID or any type supported by MongoDB

Condition query

Data preparation:

db.commentdb.insert({_id:"1",userId:"001",nickName:"Mr.Wang",content:"Come on"})
db.commentdb.insert({_id:"2",userId:"002",nickName:"Mr.Wang",content:"Come on"})
db.commentdb.insert({_id:"3",userId:"003",nickName:"Mr.Wang",content:"Come on"})
db.commentdb.insert({_id:"4",userId:"004",nickName:"Mr.Wang",content:"Come on"})
db.commentdb.insert({_id:"5",userId:"005",nickName:"Mr.Wang",content:"Come on"})

Query the data with userId 004:

db.Set name.find(query criteria)

db.commentdb.find({userId:"004"})

You can query the first data that meets the conditions by using the findOne command

db.Set name.findOne(query criteria)

db.commentdb.findOne({nickName:"Mr.Wang"})

Specifying the number of results can be called limit after the find method.

db.Set name.find().limit(quantity)

db.commentdb.find().limit(3)

2.2.3. Modifying and deleting documents

Modify syntax format:

db.Set name.update(condition,Modified data)

db.commentdb.update({_id:"1"},{content:"Work hard"})

After execution, you can find that all fields of this document except the modified fields disappear. If you use the modifier $set to implement it, this problem will not occur

The command is as follows:

db.commentdb.update({_id:"2"},{$set:{content:"Learning learning"}})

Delete syntax format:

db.Set name.remove(condition)  #Delete single
db.commentdb.remove({userId:"001"})

db.Set name.remove({})	#Delete all
db.commentdb.remove({})

Delete userId 001:

Delete all:

2.2.4 number of Statistics

Syntax format:

db.Set name.count() #Reinsert 5 pieces of data

db.comment.count()

Condition statistics:

db.Set name.count(condition)

db.comment.count({userId:"001"})

2.2.5 fuzzy query

The fuzzy query of MongoDB is realized by regular expression

Syntax format:

db.Set name.find({ :/regular expression /})

#Query all documents whose comments contain "come on, come on"
db.comment.find({content:/Come on/})

#Query comments beginning with "effort"
db.comment.find({content:/^strive/})

2.2.6. Greater than or less than or equal to

<, < =, >, > = these operators are also very common

The syntax format is as follows:

db.Set name.find({ "field" : { $gt: value }}) // Greater than: field > value

db.Set name.find({ "field" : { $lt: value }}) // Less than: field < value

db.Set name.find({ "field" : { $gte: value }}) // Greater than or equal to: field > = value

db.Set name.find({ "field" : { $lte: value }}) // Less than or equal to: field < = value

db.Set name.find({ "field" : { $ne: value }}) // Not equal to: field= value

2.2.7 inclusion and exclusion

Contains the use of the $in operator

The syntax format is as follows:

db.Set name.find({ "field" : { $in: [val, val] }})

#The query user id is 002003
db.comment.find({userId:{$in:["002","003"]}})

Excluding syntax, the format is as follows:

db.Set name.find({ "field" : { $nin: [val, val] }})

#Query user id is not 002003
db.comment.find({userId:{$nin:["002","003"]}})

2.2.8 conditional connection

If the query needs to meet more than two conditions at the same time, you need to use the $and operator to associate the conditions (equivalent to the and of SQL)

The syntax format is as follows:

db.Set name.find({ $and : [Condition, condition]})

#The query user name is Mr.Wang, and the user id is 003
db.comment.find({$and:[{nickName:"Mr.Wang"},{userId:"003"}]})

If more than two conditions are or related, you can use the $or operator to associate them in the same way as the previous and

db.Set name.find({ $or : [Condition, condition]})

#The query user id is 003, or the content is "hard work"
db.comment.find({$or:[{content:"Work hard"},{userId:"003"}]})

2.2.9 column value growth

If you want to increase or decrease the value of a column based on the original value, you can use the $inc operator

Example: db.comment.update({_id:"2"},{$inc:{num:NumberInt(1)}})

num saves a numeric type field

3, Java operation MongoDB

mongodb-driver

mongoDB driver is a Java connection mongoDB driver package officially launched by mongo, which is equivalent to JDBC driver. Understand the basic use of mongoDB driver through an introductory case.

3.1. Introducing dependency

Create a normal moven project,

<!--mongoDB rely on-->
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver</artifactId>
    <version>3.8.2</version>
</dependency>

3.2. Query all records

public class Test01 {
    public static void main(String[] args) {
        //make new connection
        MongoClient mongoClient = new MongoClient("ip address", 27017);
        //Get database object
        MongoDatabase commentdb = mongoClient.getDatabase("commentdb");
        //Get collection object
        MongoCollection<Document> commentCollection = commentdb.getCollection("comment");
        //Query records to get document collection
        FindIterable<Document> documents = commentCollection.find();
        for (Document document : documents) {
            System.out.println(document);
            System.out.println("user id: " + document.getString("userId"));
            System.out.println("User nickname:" + document.getString("nickName"));
            System.out.println("Comments:" + document.getString("content"));
        }
        // Close connection
        mongoClient.close();
    }
}

result

3.3. Single criteria query

public class Test02 {
    public static void main(String[] args) {
        //make new connection
        MongoClient mongoClient = new MongoClient("ip address", 27017);
        //Get database object
        MongoDatabase commentdb = mongoClient.getDatabase("commentdb");
        //Get collection object
        MongoCollection<Document> collection = commentdb.getCollection("comment");
        //Build query criteria
        BasicDBObject basicDBObject = new BasicDBObject("userId", "002");
        //Query records to get document collection
        FindIterable<Document> documents = collection.find(basicDBObject);
        for (Document document : documents) {
            System.out.println(document);
            System.out.println("user id: " + document.getString("userId"));
            System.out.println("User nickname:" + document.getString("nickName"));
            System.out.println("Comments:" + document.getString("content"));
        }
        // Close connection
        mongoClient.close();
    }
}

result

3.4. Insert data

public class Test03 {
    public static void main(String[] args) {
        MongoClient mongoClient = new MongoClient("ip address", 27017);
        MongoDatabase commentdb = mongoClient.getDatabase("commentdb");
        MongoCollection<Document> collection = commentdb.getCollection("comment");
        //Build new data
        HashMap<String, Object> map = new HashMap<>();
        map.put("_id","6");
        map.put("userId","006");
        map.put("nickName","Mr.White");
        map.put("content","Test insertion");
        //New field
        map.put("visits",520);
        Document document = new Document(map);
        collection.insertOne(document);
        mongoClient.close();
    }
}

3.5. Multi criteria query

public class Test04 {
    public static void main(String[] args) {
        //make new connection
        MongoClient mongoClient = new MongoClient("ip address", 27017);
        //Get database object
        MongoDatabase commentdb = mongoClient.getDatabase("commentdb");
        //Get collection object
        MongoCollection<Document> collection = commentdb.getCollection("comment");
        //Build query criteria to query those with more than 500 accesses
        BasicDBObject basicDBObject = new BasicDBObject("visits", new BasicDBObject("$gt",500));
        //Query records to get document collection
        FindIterable<Document> documents = collection.find(basicDBObject);
        for (Document document : documents) {
            System.out.println(document);
            System.out.println("user id: " + document.getString("userId"));
            System.out.println("User nickname:" + document.getString("nickName"));
            System.out.println("Comments:" + document.getString("content"));
            System.out.println("Number of visits:" + document.getInteger("visits"));
        }
        // Close connection
        mongoClient.close();
    }
}

result

4, SpringDataMongoDB

Official website homepage: https://spring.io/projects/spring-data-mongodb

As a member of the spring data family, it is used to operate the persistence layer framework of MongoDb. The bottom layer encapsulates MongoDb driver

Similar to the previous spring data elastic search

Leyou Mall (17) – comment service

1, Demand analysis

Implementation functions:

  • Addition, deletion and modification of comments
  • Comment like reply

mongodb table structure

Field nameField meaningField typeremarks
_idIDtext
orderidOrder idtext
spuidCommodity idtext
useridUser idtext
nicknameReviewer nicknametext
parentidComment idtextParent comment id, top-level comment 0
isparentIs it a top-level commentBoolean
publishtimeComment datedate
visitsViewsinteger
thumbupNumber of likesinteger
imagesPictures in commentsarray
contentComment contenttext
commentNumber of repliesinteger
iscommentAllow replyBoolean
typeEvaluation typeinteger0: very poor, 1: poor, 2: average, 3: good, 4: very good, - 1: reply to comments

Design reference tb_categoty

2, Comment service construction

2.1. Service construction

2.1.1 module creation

Parent module

Sub module

One interface module, one service module

2.1.2 Pom file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>leyou-comment</artifactId>
        <groupId>com.leyou.comment</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>leyou-comment-service</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--Service registry-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--redis rely on-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--mongodb rely on-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>com.leyou.auth</groupId>
            <artifactId>leyou-auth-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.leyou.comment</groupId>
            <artifactId>leyou-comment-interface</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

2.1.3. application.yaml configuration file

server:
  port: 8091
spring:
  application:
    name: comment-service
  cloud:
    nacos:
      discovery:
        server-addr: IP address:8848
        username: nacos
        password: nacos
  data:
    mongodb:
      host: IP address
      database: commentdb
  rabbitmq:
    host: IP address
    virtual-host: /leyou
    username: leyou
    password: leyou
  redis:
    host: IP address
    port: 8975
  jackson:
    default-property-inclusion: non_null
leyou:
  worker:
    workerId: 2
    datacenterId: 2
  jwt:
    pubKeyPath: F:\\leyou\\rsa\\rsa.pub # Public key address
    cookieName: LY_TOKEN # The name of the cookie

2.1.4 startup

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class LeyouCommentApplication {
    public static void main(String[] args) {
        SpringApplication.run(LeyouCommentApplication.class,args);
    }
}

2.2 preparations

2.2.1 entity class

public class Review implements Serializable {

    @Id
    private String _id;
    private String orderid;//Order id
    private String spuid;//Commodity id
    private String content;//Comment content
    private Date publishtime;//Comment time
    private String userid;//Comment user id
    private String nickname;//Comment user nickname
    private Integer visits;//Views of comments
    private Integer thumbup;//Number of likes in comments
    private List<String> images;//Pictures in comments
    private Integer comment;//Number of responses to comments
    private Boolean iscomment;//Can this comment be answered
    private String parentid;//The upper level id of the comment
    private Boolean isparent;//Is it a top-level comment
    private Integer type; //Types of comments

    //json transformation requires
    public Review() {
    }

    public Review(String orderid, String spuid, String content, String userid, String nickname, List<String> images, Boolean iscomment, String parentid, Boolean isparent, Integer type) {
        this.orderid = orderid;
        this.spuid = spuid;
        this.content = content;
        this.userid = userid;
        this.nickname = nickname;
        this.images = images;
        this.iscomment = iscomment;
        this.parentid = parentid;
        this.isparent = isparent;
        this.type = type;
    }
    //get and set
}

2.2.2,ReviewRepository

public interface ReviewRepository extends MongoRepository<Review,String> {
}

2.2.3 Gateway Routing

3, Function realization

3.1 paging query comments

Controller

  • Request method: GET

  • Request path: / list

  • Request parameters: Commodity id, current page number, page size, encapsulating a request parameter object:

  • Return result: returns the paging information of the comment

Here, the number of comments shows a fixed size of 20 per page. Here, a request parameter object is encapsulated

CommentRequestParam

/**
 * Comment request parameters
 */
public class CommentRequestParam {
    
    private Long spuId;//Commodity id
    private Integer page;//Current page number
    //The size of each page is not received from the front end, but fixed
    private static final Integer DEFAULT_SIZE = 20;
    private static final Integer DEFAULT_PAGE = 1;//Default page

    public Long getSpuId() {
        return spuId;
    }

    public void setSpuId(Long spuId) {
        this.spuId = spuId;
    }

    public Integer getPage() {
        if (page == null){
            return DEFAULT_PAGE;
        }
        //Do some verification when obtaining the page number, which cannot be less than 1
        return Math.max(DEFAULT_PAGE,page);
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getDefaultSize() {
        return DEFAULT_SIZE;
    }
}
@RestController
@RequestMapping("/comment")
public class CommentController {

    @Autowired
    private CommentService commentService;

    /**
     *  Paging query product comments
     * @param commentRequestParam
     * @return
     */
    @GetMapping("/list")
    public ResponseEntity<PageResult<Review>> findReviewBySpuId(@RequestBody CommentRequestParam commentRequestParam){
        Page<Review> reviews = this.commentService.findReviewBySpuId(commentRequestParam);
        if (null == reviews) return ResponseEntity.notFound().build();
        PageResult<Review> pageResult = new PageResult<>();
        pageResult.setTotalPage(reviews.getTotalPages());
        pageResult.setTotal(reviews.getTotalElements());
        pageResult.setItems(reviews.getContent());
        return ResponseEntity.ok(pageResult);
    }
}

ReviewRepository

Provide a method to query comments according to spuid

/**
 * Paging query
 * @param spuid
 * @param pageable
 * @return
 */
Page<Review> findReviewBySpuid(String spuid, Pageable pageable);

Service

public interface CommentService {

    /**
     * Query all top-level comments under a product
     * @param commentRequestParam
     * @return
     */
    Page<Review> findReviewBySpuId(CommentRequestParam commentRequestParam);
}

Implementation class:

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private ReviewRepository reviewRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * Query all top-level comments under a product
     *
     * @param commentRequestParam
     * @return
     */
    @Override
    public Page<Review> findReviewBySpuId(CommentRequestParam commentRequestParam) {
        PageRequest pageRequest = PageRequest.of(commentRequestParam.getPage() - 1, commentRequestParam.getDefaultSize());
        return this.reviewRepository.findReviewBySpuid(commentRequestParam.getSpuId()+"",pageRequest);
    }
}

3.2. Comment

  • Request method: POST

  • Request path: None

  • Request parameter: Review comment object

  • Return result: status code 201

Controller

/**
 * Add a comment
 * @param review
 * @return
 */
@PostMapping
public ResponseEntity<Void> addReview(@RequestBody Review review){
    boolean flag = this.commentService.addReview(review);
    if (!flag) return ResponseEntity.badRequest().build();
    return ResponseEntity.status(HttpStatus.CREATED).build();
}

Service

/**
 * Add a comment
 * @param review
 * @return
 */
boolean addReview(Review review);

Implementation class:

/**
 * Add a comment
 *
 * @param review
 * @return
 */
@Override
@Transactional
public boolean addReview(Review review) {
    //There are two situations: 1. Top level parent comments; 2. Follow up comments or replies
    //Judge whether it is the first comment
    if (review.getIsparent()){
        //If yes, go to mongo to check whether there are comments
        Query query = new Query();
        //A comment can be determined according to user id, order id and spuid
        query.addCriteria(Criteria.where("userid").is(review.getUserid()));
        query.addCriteria(Criteria.where("orderid").is(review.getOrderid()));
        query.addCriteria(Criteria.where("spuid").is(review.getSpuid()));
        List<Review> reviews = this.mongoTemplate.find(query, Review.class);
        if (reviews.size() > 0 && reviews.get(0).getIsparent()) return false;
    }
    review.set_id(this.idWorker.nextId()+"");
    review.setPublishtime(new Date());
    review.setComment(0);
    review.setThumbup(0);
    review.setVisits(0);
    //Parent class id exists
    if (null != review.getParentid() && !"".equals(review.getParentid())){
        //Set the number of parent comments + 1, the number of views + 1, and isparent to true
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(review.getParentid()));
        Update update = new Update();
        update.inc("comment",1);
        update.inc("visits",1);
        update.set("isparent",true);
        this.mongoTemplate.updateFirst(query,update,"review");
    }
    //Save comments
    this.reviewRepository.save(review);
    return true;
}

Here, it is determined whether the comment is the user's first comment on the product. There are two types of comments: 1. Parent comment 2. Follow up comment or reply

3.3 modification comments

Controller

  • Request method: PUT

  • Request path: None

  • Request parameter: Review comment object

  • Return result: status code 200

/**
 * Update a comment
 * @param review
 * @return
 */
@PutMapping
public ResponseEntity<Void> updateReview(@RequestBody Review review){
    this.commentService.updateReview(review);
    return ResponseEntity.ok().build();
}

Service

/**
 * Update a comment
 * @param review
 * @return
 */
void updateReview(Review review);

Implementation class:

/**
 * Update a comment
 *
 * @param review
 * @return
 */
@Override
public void updateReview(Review review) {
    this.reviewRepository.save(review);
}

3.4 delete comments

Controller

  • Request method: DELETE

  • Request path: None

  • Request parameter: comment id

  • Return result: status code 200

/**
 * Delete comments by comment id
 * @param id
 * @return
 */
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteReview(@PathVariable("id") String id){
    this.commentService.deleteReview(id);
    return ResponseEntity.ok().build();
}

Service

/**
 * Delete comments by comment id
 * @param id
 * @return
 */
void deleteReview(String id);

Implementation class:

/**
 * Delete comments by comment id
 *
 * @param id
 * @return
 */
@Override
public void deleteReview(String id) {
    this.reviewRepository.deleteById(id);
}

3.5. Query comments by id

Controller

  • Request method: GET

  • Request path: None

  • Request parameter: comment id

  • Return result: comment object

/**
 * Query comments by comment id
 * @param id
 * @return
 */
@GetMapping("/{id}")
public ResponseEntity<Review> findReviewById(@PathVariable("id") String id){
    Review review = this.commentService.findOne(id);
    if (null == review) return ResponseEntity.notFound().build();
    return ResponseEntity.ok(review);
}

Service

/**
 * Query comments by comment id
 * @param id
 * @return
 */
Review findOne(String id);

Implementation class:

/**
 * Query comments by comment id
 *
 * @param id
 * @return
 */
@Override
public Review findOne(String id) {
    Optional<Review> optional = this.reviewRepository.findById(id);
    //Judge whether it is empty
    return optional.orElse(null);
}

3.6. Comment and praise

Like is to add one to the field thumbup and use the MongoTemplate class to operate on a column without having to query all of them. That's inefficient. Using the self increasing function inc to realize thumbup plus one

Use redis to control that the same user cannot repeat likes

Here, jwt authentication related classes and configurations are introduced

Controller

  • Request method: PUT

  • Request path: / thumb/{id}

  • Request parameter: comment id

  • Return result: boolean

@Autowired
private StringRedisTemplate redisTemplate;

private final String THUMBUP_PREFIX = "thumbup:";
/**
 * Number of likes for comments + 1
 * @param id
 * @return
 */
@PutMapping("/thumbup/{id}")
public ResponseEntity<Void> updateThumbup(@PathVariable("id") String id){
    //First, judge whether the user has liked
    UserInfo userInfo = LoginInterceptor.getLoginUser();
    String result = this.redisTemplate.opsForValue().get(THUMBUP_PREFIX + userInfo.getId() + "-" + id);
    if (StringUtils.isNotBlank(result)) return ResponseEntity.badRequest().build();
    Boolean flag = this.commentService.updateThumbup(id);
    if (!flag) return ResponseEntity.badRequest().build();
    //redis saves the user's likes
    this.redisTemplate.opsForValue().set(THUMBUP_PREFIX + userInfo.getId() + "-" + id,"1");
    return ResponseEntity.ok().build();
}

Service

/**
 * Number of likes for comments + 1
 * @param id
 * @return
 */
Boolean updateThumbup(String id);

Implementation class:

/**
 * Number of likes for comments + 1
 *
 * @param id
 * @return
 */
@Override
public Boolean updateThumbup(String id) {
    Query query = new Query();
    query.addCriteria(Criteria.where("_id").is(id));
    Update update = new Update();
    update.inc("thumbup",1);
    UpdateResult result = this.mongoTemplate.updateFirst(query, update, "review");
    return result.wasAcknowledged();
}

3.7 comment visits

Controller

  • Request method: PUT

  • Request path: / visit/{id}

  • Request parameter: comment id

  • Return result: status code 200

When a user clicks a comment to view it, he requests the interface and adds the number of visits to the comment + 1

/**
 * + 1 for comment views
 * @param id
 * @return
 */
@PutMapping("/visit/{id}")
public ResponseEntity<Void> updateVisit(@PathVariable("id")String id){
    Boolean flag = this.commentService.updateVisit(id);
    if (!flag) return ResponseEntity.badRequest().build();
    return ResponseEntity.ok().build();
}

Service

/**
 * + 1 for comment views
 * @param id
 * @return
 */
Boolean updateVisit(String id);

Implementation class:

/**
 * + 1 for comment views
 *
 * @param id
 * @return
 */
@Override
public Boolean updateVisit(String id) {
    Query query = new Query();
    query.addCriteria(Criteria.where("_id").is(id));
    Update update = new Update();
    update.inc("visits",1);
    UpdateResult result = this.mongoTemplate.updateFirst(query, update, "review");
    return result.wasAcknowledged();
}

4, Interface test

To create a test class:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = LeyouCommentApplication.class)
public class CommentTest {

    @Autowired
    private ReviewRepository reviewRepository;

    /**
     * Add 50 top-level comment data for the product with spuId 2
     */
    @Test
    public void createReview(){
        for (int i = 0; i < 50; i++) {
            String orderId = "123456789";
            String spuId = "2";
            String content = "Huawei really doesn't have a card"+i;
            String userId = (35 + i) + "";
            String nickname = "username"+i;
            List<String> images = new ArrayList<>();
            boolean iscomment = i % 2 == 0;
            String parentId = 0 + "";
            boolean isparent = true;
            int type = i % 5;
            Review review = new Review(orderId,spuId, content, userId, nickname, images, iscomment, parentId,isparent,type);
            this.reviewRepository.save(review);
        }
    }
}

Through the API post tool test, request the login interface after opening the global cookie function

4.1 paging query

4.2. Comment

Data entry:

{
    "orderid": "123456789",
    "spuid": "2",
    "content": "Huawei really doesn't have a card",
    "publishtime": null,
    "userid": "35",
    "nickname": "username0",
    "images": [],
    "iscomment": true,
    "parentid": "0",
    "isparent": true,
    "type": 0
}

Comment again:

Comment reply

Data entry:

{
    "spuid": "2",
    "content": "It's true! Huawei really doesn't have a card",
    "userid": "35",
    "nickname": "username1",
    "images": [],
    "iscomment": true,
    "parentid": "611d00af1072831019162bdc",
    "isparent": false,
    "type": -1
}

Query parent comments:

4.3 modification comments

4.4. Query comments by id

Get the id of the previously modified comment through paging query:

Query the data by id:

4.5 delete comments

Delete just comment

Re query this comment:

4.6. Comment and praise

Like the comment with id: 611d00af1072831019162bdb

Query this comment

5, Service call

5.1. Order status modification

5.1.1,OrderApi

@RequestMapping("/order")
public interface OrderApi {
    /**
     * Update order status
     * @param id
     * @param status
     * @return
     */
    @PutMapping("/{id}/{status}")
    Boolean updateOrderStatus(@PathVariable("id") Long id, @PathVariable("status") Integer status);
}

5.1.2,OrderClient

Introduce dependency

<dependency>
    <groupId>com.leyou.order</groupId>
    <artifactId>leyou-order-interface</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
@FeignClient(value = "order-service")
public interface OrderClient extends OrderApi {
}

5.1.3,CommentServieImpl

Add in the addReview method in CommentServieImpl:

Keywords: MongoDB

Added by jackyhuphp on Tue, 07 Sep 2021 00:59:32 +0300