在 mongo 文档中创建一个自动递增字段

creating an auto increment field within a mongo document

在我的 Spring 引导应用程序中,我使用 Spring-Data MongoDB,并且我有一个代表用户的简单 POJO:

@EqualsAndHashCode
public class User implements Storable {

  @Id
  public ObjectId id;

  @Getter @Setter public String firstName;
  @Getter @Setter public String lastName;
  @Getter @Setter public long userNum;
  @DBRef(lazy = true)
  @Getter @Setter public List<Section> sections = new ArrayList<Section>();

... 
rest of class omitted
...

}

我的 UserController 看起来像这样:

@Controller
public class UserController {

  @Autowired
  UserRepository repository;

  @ModelAttribute("allSections")
  public List<Section> getSections() {
    return sectionRepository.findAll();
  }

  @RequestMapping(value = "/users/new", method = RequestMethod.POST)
  public String newUser(@ModelAttribute("user") User user) {
    User newUser = new User();
    newUser.userNum = user.userNum;
    newUser.firstName = user.firstName;
    newUser.lastName = user.lastName;
    newUser.sections = user.sections;
    newUser = repository.save(newUser);

    for (Section section : newUser.sections) {
      section.addToUsers(newUser);
      sectionRepository.save(section);
    }

    return "redirect:/users";
  }
... rest of controller omitted 
}

请注意,我要自动生成的字段不是 ID 字段。

我希望 userNum 属性自动递增,这样创建并存储在数据库中的第一个用户对象从某个值开始...比如 9000,之后创建的每个用户都会递增1.

我有哪些选择可以做到这一点?我见过使用 JPA 的 @GeneratedValue 的示例,其他示例依赖于自定义 Mongo 查询来创建序列集合,但我都无法正常工作...

创建计数器集合:

public class Counter {

    @Id
    private String id;

    private long seq;

    public Counter(String id, long seq) {
        this.id = id;
        this.seq = seq;
    }

    // Getters and setters
}

然后是一个 MongoRepository:

@Repository
public interface CounterRepository extends MongoRepository<Counter, String> {}

还有一个Service/DAO:

@Service
public class CounterServiceImpl implements CounterService {

    @Autowired
    private CounterRepository counterRepository;

    @Override
    public long getNext(String sequenceId) {
        Counter counter = counterRepository.findOne(sequenceId);
        long id = counter.getSeq();
        counter.setSeq(id + 1);
        counterRepository.save(counter);
        return id;
    }
}

好的,我已经弄明白了,这就是我实现它的方式:

class for userNum,这是一个简单的POJO

public class UserNum {

  @Id
  private ObjectId id;

  @Getter
  @Setter
  public long seq;

  public UserNum(long seq) {
    this.seq = seq;
  }

}

UserNumRepository 有一个方法定义了 returns 保存到集合中的最后一个 UserNum

@Repository
public interface UserNumRepository extends MongoRepository<UserNum, String> {
  UserNum findTopByOrderByIdDesc();
}

UserNumService 简单地找到序列中的最后一个数字并创建下一个数字,然后保存它和 returns 该数字。 UserNumService 是具有一个方法签名的接口。这创建了所有已创建和使用的 userNums 的集合。

@Service
public class UserNumServiceImpl implements UserNumService {

  @Autowired
  private UserNumRepository userNumRepository;

  @Override
  public long getNext() {
    UserNum last = userNumRepository.findTopByOrderByIdDesc();
    long lastNum = last.seq;
    UserNum next = new UserNum(lastNum + 1);
    userNumRepository.save(next);
    return next.seq;
  }
}

在 Application.java 中,您可以使用起始编号或从 mongo shell.

为集合播种
@Autowired UserNumRepository userNumRepository;

public void run(String... args) throws Exception {

    userNumRepository.deleteAll();
    // start the sequence at 9000
    userNumRepository.save(new UserNum(9000)); 
}

现在您终于可以在需要发出新的 userNum 时简单地使用该服务,也许在构造函数中。