0..n具有偏移量和极限的结果转换产生不准确的结果

时间:2019-04-26 08:54:37

标签: java postgresql querydsl

我已经搜索了正确的答案,但是很遗憾,没有找到QueryDsl SQL模块的任何有效解决方案。 我正在尝试在自定义属性上使用左连接来获取具有0..n关系的简单实体:

<script>
import firestore from 'firebase/firestore'
import { mapGetters } from 'vuex'
import SingleMessage from './SingleMessage'
import MessageForm from './MessageForm'

export default {
  name: 'messages',
  components: {
    SingleMessage,
    MessageForm,
  },
  data() {
    return {
      channelsRef: firebase.firestore().collection('channels'),
      messages: [],
      channel: '',
      unsubscribe: null
    }
  },
  computed: {
    ...mapGetters(['currentChannel']),
  },
  watch: {
    currentChannel: function(newValue, oldValue) {
          this.messages = [];
          if (this.unsubscribe) {
            this.unsubscribe(); 
            this.addListeners(newValue);
          } else {
            this.addListeners(newValue);
          }
    }
  },
  methods: {
    addListeners(newValue) {
      this.unsubscribe = this.channelsRef
        .doc(newValue.id)
        .collection('messages')
        .onSnapshot(snapshot => {
          snapshot.docChanges().forEach(change => {
            if (change.type == 'added') {
              let doc = change.doc
              this.messages.push({
                id: doc.id,
                content: doc.data().content,
                timestamp: doc.data().timestamp,
                user: doc.data().user,
              });
            }
          });
        });
      console.log('[addListeners] channel:', newValue.id)
    }
  }
}
</script>

为了能够填充dto,我将结果转换如下:

class Parent {
    private Long id;
    private String uuid;
    private Set<Child> children;
}

class Child {
    private Long id;
    private String uuidRef;
}

有些父行具有多个子关​​系。 一切工作正常,除非我为分页目的添加查询额外的限制和偏移量。我们希望获得前20个结果,所以我要添加.offset(0).limit(20)。

在db中,有2个父记录,每个记录有2个子行。经过变换/分组后,我只能得到18行/对象。我知道这是由于SQL查询本身造成的,因为它返回左连接的行作为单独的结果行,并且转换在内存中完成,但是我想知道这是否可以以某种方式在SQL模块上处理。我不想使用JPA,因为这是一个很小的项目,只有很少的表,并且JPA / Hibernate会显得过大。 SQL模块非常适合此:)

在PostgreSQL 11.2中使用QueryDsl SQL 4.2.1

1 个答案:

答案 0 :(得分:0)

我想说的是,JPA也不会“正确”地处理该问题,至少在尝试一次性获取父母及其子女时不会如此。正如您已经注意到的那样,问题在于偏移量和限制将应用于结果,并且如果父级具有多个子级,则联接会导致较少的父级被加载(或者如果只有一个父级,则只有一部分父级的子级被加载)。许多)。因此,您必须将偏移量和限制应用于代表每行父对象的对象。

您可以尝试这样的操作(我不知道QueryDsl,所以我只会使用伪SQL):

select ... from parent p join children c on ...
   where p.id in ( select distinct id from parent order by whatever offset x limit y )

因此,您要做的是确定子查询中20个父母的ID,然后将这些父母及其孩子加载,这可能会导致超过20个结果行(如果您的2个父母有2个父母,则您的情况下为22行)儿童和其他18个孩子最多只能有1个。