当前位置: 首页 > 知识库问答 >
问题:

Spring MongoDB标记@Query,其中$group不起作用

须彭亮
2023-03-14

注意:向下查看已编辑的消息。

我试着模仿这个问题:

db.sentiments.aggregate([
{"$group" : {_id:{theme_id:"$theme",sentiment_id:"$sentiment"}, count:{$sum:1}}},
{"$sort":{"_id.theme_id":1}} ])

这是我为了模仿它而生成的代码:

    @RepositoryRestResource(collectionResourceRel = "sentiments", path = "sentiments")
public interface SentimentsRepository extends MongoRepository<Sentiments, String> {
    Long countByTheme(@Param("theme") String theme);

@Query(value ="[\n" +
        "    {\"$group\" : {_id:{theme_id:\"$theme\",sentiment_id:\"$sentiment\"}, count:{$sum:1}}},\n" +
        "\t{\"$sort\":{\"_id.theme_id\":1}}\n" +
        "]",count = true)
List<Object> comptarSentiments();

}这个代码返回给我这个错误:

"exception": "org.springframework.data.mongodb.UncategorizedMongoDbException",


"message": "Can't canonicalize query: BadValue unknown operator: $group; nested exception is com.mongodb.MongoException: Can't canonicalize query: BadValue unknown operator: $group",

事实上,我是一个乞讨者,所以我很迷茫,有人知道我该怎么做吗?

谢谢,对不起,我的英语不好,不是我的母语。

[编辑]---------------------------------------正如肖恩·克拉克(Shawn Clark)所写的评论,不可能这样做,为了实现这一点,您需要创建一个customRepository。

Spring数据的MongoTemplate和MongoRepository之间有什么区别?

我一直试图这样做,但似乎有点不对劲,以下是我的新代码:

@RepositoryRestResource(collectionResourceRel = "sentiments", path = "sentiments")
public interface SentimentsRepository extends CrudRepository<Sentiments, String>, CustomSentimentsRepository {

//Other methods...

}

public interface CustomSentimentsRepository {

    List<CountResult> yourCustomMethod();

    class CountResult{
        String theme;
        String sentiment;
        int total;
    }
}

public class SentimentsRepositoryImpl implements CustomSentimentsRepository {
    private final MongoOperations operations;


    @Autowired
    public SentimentsRepositoryImpl(MongoOperations operations) {

        Assert.notNull(operations, "MongoOperations must not be null!");
        this.operations = operations;
    }

    @Override
    public List<CountResult> yourCustomMethod(){
        Aggregation agg = Aggregation.newAggregation(
                Aggregation.group("theme","sentiment").count().as("total"),
                Aggregation.project("theme","sentiment").and("total").previousOperation(),
                Aggregation.sort(Sort.Direction.DESC, "theme")
        );

        //Convert the aggregation result into a List
        AggregationResults<CountResult> groupResults
                = operations.aggregate(agg,"sentiments",  CountResult.class);
        //List<CountResult> result = groupResults.getMappedResults();

        return groupResults.getMappedResults();
    }
}

我甚至无法破解这个代码,我总是得到一个404。

共有3个答案

穆建元
2023-03-14

您可以在Spring data mongodb 2.2中使用@Aggration。X版本:

@聚合(管道 = {"{ '$组': { '_id:$lastname, name:{$addToSet:'$?0' } } }", "{ '$:{'lastname':-1 } }"}) 列表

狄承望
2023-03-14

我终于设法解决了这个问题,似乎它与控制器和innerClass CountResult中的atribute“total”类型有关,它需要是一个字符串(这非常重要,否则Aggregation.project将失败)。最后的代码如下:

public interface CustomSentimentsRepository {

    List<CountResult> myCountGroupByThemeAndSentiment();

    class CountResult{
        public String theme;
        public String sentiment;
        public String total;
    }
}

public class SentimentsRepositoryImpl implements CustomSentimentsRepository {
    private final MongoTemplate mongoTemplate;


    @Autowired
    public SentimentsRepositoryImpl(MongoTemplate mongoTemplate) {

        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public List<CountResult> myCountGroupByThemeAndSentiment(){
        Aggregation agg = Aggregation.newAggregation(
                Aggregation.group("theme","sentiment").count().as("total"),
                Aggregation.project("theme","sentiment").andInclude("total"),


        Aggregation.sort(Sort.Direction.ASC,"theme","sentiment")
    );


    AggregationResults<CountResult> groupResults
            = mongoTemplate.aggregate(agg,"sentiments",  CountResult.class);


        return groupResults.getMappedResults();
    }
}

@RepositoryRestResource(collectionResourceRel = "sentiments", path = "sentiments")
public interface SentimentsRepository extends CrudRepository<Sentiments, String>, CustomSentimentsRepository {
    //Other methods

}

@RestController
@RequestMapping(value = "sentiments/search")
public class ChartsController {
    @Autowired
    private SentimentsRepository sentimentsRepository;

    @RequestMapping(value = "myCountGroupByThemeAndSentiment", method = RequestMethod.GET)
    public ResponseEntity<?> yourCustomMethod() {
        List<?> count=sentimentsRepository.myCountGroupByThemeAndSentiment();
        return new ResponseEntity(count, HttpStatus.OK);
    }

}
苗冯浩
2023-03-14

根据我发现的信息,您不能在MongoRepository方法上执行@Query的复杂操作。在这种情况下,您可能希望创建一个类,并使用mongoTem板来使用聚合函数查询数据存储库来实现comptarSentiments()方法。然后创建一个公开REST终结点的控制器类,并让它调用存储库。

一旦你开始在Mongo中进行复杂的查询,你就失去了@RepositoryRestResource的便利性,你必须自己将RESTendpoint连接到存储库。

Spring Data REST:MongoDB存储库的自定义查询

实现Spring数据存储库的定制方法并通过REST公开它们

 类似资料:
  • 编辑:一位评论者正确地指出,事实上,我正在处理的HTML代码都在一个标记中,这似乎对这个特定案例产生了决定性的影响。 我试图在任何级别检索元素中的所有元素。事实上,我也需要做一些额外的检查,所以我需要使用。xpath,而不是通过。标记名。但是,顺便说一句。xpath在某种程度上不起作用,即使没有检查。(当然,其他检查也会失败——我只是提供了一个最小的例子)。 我的代码: 第一行是用来调试的,以确保

  • 它给了我编译错误 cvc-complex-type.2.4.c:匹配通配符是严格的,但找不到元素“身份验证管理器”的声明 和在这一行找到的多个注释: null 请澄清我错在哪里

  • 问题内容: 我有一个从搜索返回的对象的索引。该模板具有ng-repeat,其中项目的URL是根据模型中的数据构造的,但在最终标记中,“ a”标记无效。ng- href和href正确,单击链接但页面未加载时,URL栏会更改。点击后刷新浏览器确实会获得页面。因此,Angular中的某些内容正在更改URL栏,但不会触发加载??? 无法在jsfiddle中进行复制,因为问题似乎出在$ resource.q

  • 问题内容: 我正在开发一个非常消耗内存的应用程序,并且想要使用largeHeap- Tag,这应该为应用程序提供更多的内存。无论我在AndroidManifest.xml中将此标签设置为什么,它对我给定的实际内存都没有影响。我正在这样读出我的最大内存: 我的清单看起来像这样: 我在模拟器中运行3.1,上面的日志输出始终为48MB。有人可以帮忙吗? 问题答案: 使用ActivityManager.g

  • 当屏幕宽度大于700px时,iframe标签的宽度为400px,高度为225px。如果屏幕宽度小于700px,那么iframe标签的宽度将是屏幕的50%,高度将是屏幕的28.13%。 我试过用这个代码。但不管用。 问题出在哪里?