Java 使用spring数据从mongodb中随机选取条目

Java 使用spring数据从mongodb中随机选取条目,java,spring,mongodb,spring-data,spring-data-mongodb,Java,Spring,Mongodb,Spring Data,Spring Data Mongodb,我正在尝试使用spring从mongodb获取x个随机条目 我的存储库如下所示 public interface StoryRepository extends MongoRepository<Story, Long> { @Query("{$sample: {size: ?0} }") List<Story> findRandom(int quantity); } public class Story { @Id private lon

我正在尝试使用spring从mongodb获取x个随机条目

我的存储库如下所示

public interface StoryRepository extends MongoRepository<Story, Long> {
    @Query("{$sample: {size: ?0} }")
    List<Story> findRandom(int quantity);
}
public class Story {
    @Id
    private long id;
    private String by;
    private int descendants;
    private List<Long> kids;
    private int score;
    private long time;
    private String title;
    private String type;
    private String url;

    private By author;


    public long getId() {
        return id;
    }

    ...
}
<?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">
<modelVersion>4.0.0</modelVersion>

<groupId>dk.tons.hackernews.backend</groupId>
<artifactId>tons-hackernews-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Backend</name>
<description>Tons Hacker News Backend</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
我还尝试了下面的方法,得到了完全相同的错误

    public List<Story> findRandom(final int quantity) {
        CustomAggregationOperation customAggregationOperation = new CustomAggregationOperation(new BasicDBObject("$sample", new BasicDBObject("size", quantity)));
        TypedAggregation<Story> aggregation = new TypedAggregation<>(Story.class, customAggregationOperation);
        AggregationResults<Story> aggregationResults = mongoTemplate.aggregate(aggregation, Story.class);
        return aggregationResults.getMappedResults();
    }
public List findRandom(最终整数数量){
CustomAggregationOperation CustomAggregationOperation=新的CustomAggregationOperation(新的BasicDBObject($sample),新的BasicDBObject(“size”,quantity));
TypedAggregation聚合=新的TypedAggregation(Story.class,customAggregationOperation);
AggregationResults AggregationResults=mongoTemplate.aggregate(聚合,Story.class);
返回aggregationResults.getMappedResults();
}
我的故事课如下

public interface StoryRepository extends MongoRepository<Story, Long> {
    @Query("{$sample: {size: ?0} }")
    List<Story> findRandom(int quantity);
}
public class Story {
    @Id
    private long id;
    private String by;
    private int descendants;
    private List<Long> kids;
    private int score;
    private long time;
    private String title;
    private String type;
    private String url;

    private By author;


    public long getId() {
        return id;
    }

    ...
}
<?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">
<modelVersion>4.0.0</modelVersion>

<groupId>dk.tons.hackernews.backend</groupId>
<artifactId>tons-hackernews-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Backend</name>
<description>Tons Hacker News Backend</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
公共类故事{
@身份证
私人长id;
私人串接;
私生子孙;
私人名单儿童;
个人智力得分;
私人时间长;
私有字符串标题;
私有字符串类型;
私有字符串url;
作者私人;
公共长getId(){
返回id;
}
...
}
我的pom文件如下

public interface StoryRepository extends MongoRepository<Story, Long> {
    @Query("{$sample: {size: ?0} }")
    List<Story> findRandom(int quantity);
}
public class Story {
    @Id
    private long id;
    private String by;
    private int descendants;
    private List<Long> kids;
    private int score;
    private long time;
    private String title;
    private String type;
    private String url;

    private By author;


    public long getId() {
        return id;
    }

    ...
}
<?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">
<modelVersion>4.0.0</modelVersion>

<groupId>dk.tons.hackernews.backend</groupId>
<artifactId>tons-hackernews-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Backend</name>
<description>Tons Hacker News Backend</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

4.0.0
dk.tons.hackernews.backend
hackernews后端
0.0.1-快照
罐子
后端
黑客新闻后端
org.springframework.boot
spring启动程序父级
1.4.0.1发布
UTF-8
UTF-8
1.8
org.springframework.boot
spring启动程序数据mongodb
org.springframework.boot
弹簧启动启动器数据rest
com.h2数据库
氢
运行时
org.springframework.boot
弹簧起动试验
测试
org.springframework.boot
springbootmaven插件

有什么线索吗?

为什么失败了 您使用了一个自定义查询
@query(“{$sample:{size:?0}”)
和/或像这样定义了
CustomAggregationOperation
(使用
context.getMappedObject
):

两者都通过
QueryMapper.getMappedKeyword
,这是引发错误的spring方法。如果打开spring的
QueryMapper.getMappedKeyword
,您将看到:

protected DBObject getMappedKeyword(Keyword keyword, MongoPersistentEntity<?> entity) {
    ...
    if (keyword.isSample()) {
        return exampleMapper.getMappedExample(keyword.<Example<?>> getValue(), entity);
    }
    ...
}

public boolean isSample() {
    return "$sample".equalsIgnoreCase(key);
}

如果您看一下其他操作是如何编写的,那么我们对()的理解是正确的:

(2) 如果你想的话,让它成为通用的 要使CustomOperation保持通用性,您可以这样定义它:

CustomGenericOperation customGenericOperation = 
    new CustomGenericOperation(new BasicDBObject("$sample", new BasicDBObject("size", 1)));    
...

public class CustomGenericOperation implements AggregationOperation {
    private DBObject dbObject;
    public CustomGenericOperation(DBObject dbObject){
        this.dbObject = dbObject;

    }
    @Override
    public DBObject toDBObject(final AggregationOperationContext context) {
        return dbObject;
    }
}
(3) 另类 您可以:

  • 获取Java中的随机数(假设您首先检索集合中的文档数)
  • 在聚合查询中
    • 限制(随机数)
    • 升序排序
    • 限额(1)
简言之,使用随机数限制并获取最后一个文档:

$ db.story.aggregate([{$limit: RANDOM_NUMBER},{$sort: {_id: 1}}, {$limit: 1}])

Example
Story
的子类吗?不,我不知道它是什么。。。我没有用它。请发布你的
故事
课程和你的POM/Gradle文件。完成。。。Stackoverflow迫使我写的比完成的还多…(请注意,根据个人经验,MongoDB对于这样的模型是一个糟糕的选择,因为您在数据对象之间有很多关系:您必须手动完成所有连接。)但这不是一个bug吗?无法使用$sample操作符,我的意思是我不会说这是一个bug。。只是我们现在不知道如何使用?:)谢谢哇!但是@Query(“{$sample:{size:?0}}”)不起作用,这不是一个问题吗?我仍然认为他们的示例有一些想法,只是没有文档记录。然而,我很少看到对$sample支持的请求:和。这表明我们目前的解决方案是正确的!