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

用QueryDSL和Mongo转换地图值类型

虞博涛
2023-03-14

我的MongoDB数据库中的文档有两个主要属性——标头和有效负载。我的POJO将标头保存为带有键字符串和值字符串的地图。但是,由于我设置的地图限制,我的标头地图中有一个时间戳字段被QueryDSL读取为字符串。

如何使用QueryDSL比较保存为字符串的时间戳值(Long)?

我是否应该创建标头以将键类型字符串映射到值类型 Object?如果是这种情况,当返回的路径现在是简单路径而不是允许更复杂比较的路径(如字符串路径或日期时间路径)时,如何执行诸如 .starts 和 .include 之类的操作?

我的文档对象:

@Document
public class Event {

    @Id
    private String id; 
    public Map<String, String> headers;
    public Object payload;

创建谓词的方法,该谓词接受headers Map对象,并将其与queryDSL的qEvent headers映射对象进行比较。

    public Predicate createQuery(Map<String, String> headers, Long startTime, Long endTime) {
            QEvent qEvent = QEvent.event;
            BooleanBuilder builder = new BooleanBuilder();
            if (headers != null) {
                if (isValid(headers.get("stringID")))
                    builder.and(qEvent.headers.get("stringID").containsIgnoreCase(headers.get("stringID")));
                if (isValid(headers.get("type"))) 
builder.and(qEvent.headers.get("type").containsIgnoreCase(headers.get("type")));
....
//additional String comparisons on fields inside headers
//this is where the StringPath created by queryDSL suffices for everything except for Long/Timestamp values

return builder.getValue(); 
}

我曾考虑过为timestamp字段创建自己的动态路径,但在以下情况之后被卡住了:

    PathBuilder<Event> entityPath = new PathBuilder<Event>(Event.class, "entity"); 
    PathBuilder<Timestamp> timestamp = entityPath.getMap("headers", String.class, Timestamp.class).get("timestamp");

以上是一个正确的开始吗?使用Mongo作为我的底层数据库是否意味着上面的第一行实际上应该如下:

PathBuilder<Event> documentPath = new PathBuilder<Event>(Event.class, "document"); 

我已经被困在这个问题上一段时间了,任何帮助都将不胜感激。谢谢。

共有1个答案

裴星洲
2023-03-14

以防我的问题不明显,我想多了。

这个问题的解决方案是简单地创建我自己的“Headers”对象——原始POJO中的一个嵌套类。

事件类应如下所示:

@Document
public class Event {

    @Id
    private String Id; 
    public Headers headers;
    public Object payload;

在我的Event类中有一个静态Headers对象,它的字段与我所需要的相关——其中之一是“时间戳”。

public static class Headers {

        //some more fields inside my Headers object
        //can be found here

        @Field
        public Long timestamp; 

        @Field
        public Long jms_timestamp; 

        @Field
        public String originator; 

        @Field
        public String eventName;

然后查询谓词的方法保持不变,并且可以相应地比较long/Strings/任何其他类型。

 类似资料:
  • 我有一个任务:返回一个公司地图,其中键是它的名称,值是存储为String的员工列表,由和组成,用空格分隔。这是我的解决方案和它的工作罚款: 所以我的问题是,如何转换

  • 问题内容: 如何转换 为? 这不起作用: 问题答案: 如果您只包含,则可以这样操作: 如果不是,则可以替换 为。

  • 我有一张这样的地图<代码>地图 钥匙是数字1,2,3,4。。。学生对象是: 我想做的是把它转换成地图 我可以使用这些代码对地图进行分组,但summingDouble不适用于BigDecimal。此外,我无法将我的studentMap转换为StudentInfo地图:( 我的学生信息对象是:

  • 问题内容: 我需要转换为。我已经为这个问题苦苦挣扎了一段时间。 很明显如何转换为: 但是我找不到解决最初的问题。有一些易于使用的Java-8方法吗? 问题答案: 我想您很亲密,您需要将这些条目添加到a 并从那里收集。我使用了已经存在的,但是您也可以使用某种。 好吧,如果您不想增加这些实例的额外开销,则可以做些不同:

  • 我有一个java map:

  • 问题内容: 我一直在研究Jackson,但似乎我必须将Map转换为JSON,然后将所得的JSON转换为POJO。 有没有一种方法可以将Map直接转换为POJO? 问题答案: 好吧,您也可以使用Jackson来实现。(由于您正在考虑使用杰克逊,因此似乎更舒适)。 使用的方法: 无需转换为JSON字符串或其他内容;直接转换的速度要快得多。