Meteor collection hook direct not working #147

Hello, I’m going to talk about a bug we noticed. We use priority redis oplog and we don’t have the problem when we don’t use it. During the use of meteor-collection-hook with publishComposite, we enter the before hook in the collection queries we make with direct and our queries do not work correctly.

Example:

...
    children: [
      {
        find(session) {
          this.unblock();
          return Channels.direct.find({ _id: session.channelId });
        }
    ]
 ...

Normal publish works correctly:

Meteor.publish('name', function () {
  return Channels.direct.find({  _id: session.channelId })
});

I’m open to any help and ideas. Thank you so much.

I’m having trouble understanding what is meant here. Could you please explain?

I apologize for my English. While using “direct” to query without going into the “before” and “after” hooks that we set while using meteor-collection-hook, the “before” hook is also entered.

Re: Meteor collection hook direct not working · Issue #147 · Meteor-Community-Packages/meteor-publish-composite · GitHub

If I understand correctly,

When you use Channels.direct.find() without specifying the life cycle hook, you get expected behavior.

But when you try to do the same thing in with publishComposite using the .before hook, it fails.

Is that right?

If so, what is the expected behavior and what do you see?

Namely, I have a “softRemove” package that I wrote myself. Soft remove adds “removedAt” to the removed data. I use Collection.direct.find to bypass this.

The sample code of the package is below.

export const name = 'soft-remove';
import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions';

checkNpmVersions({
  'simpl-schema': '1.12.0'
}, 'bordo:soft-remove');

const SimpleSchema = require('simpl-schema');
SimpleSchema.extendOptions(['denyInsert']);

const _schema = new SimpleSchema({
  removedAt: {
    denyInsert: true,
    optional: true,
    type: Date
  }
});

const _beforeFindHook = function (_userId, _selector, _options) {
  _selector.removedAt = { $exists: false };
 };

Mongo.Collection.prototype.softRemovable = function () {
  const collection = this;
  collection.attachSchema(_schema);

  collection.softRemove = function (selector) {
    collection.update(selector, {
      $set: {
        removedAt: new Date()
      }
    }, { multi: true });
  };

  collection.before.find(_beforeFindHook);
  collection.before.findOne(_beforeFindHook);
};

I was looking at taking a similar approach for soft removes. Curious, are you still using {$exists: false} for your beforeFindHook? It looks like that will require a full collscan. Based on that, did you opt for a different approach?

It’s better to add an isDeleted field to the schema with a default value of false and do queries with isDeleted: false.

Check out ESR rule, it will help a lot when thinking about your schema and queries.

Thanks, was thinking the same. Was wondering if anyone had discovered a clever alternative that didn’t involve setting a deleted flag for all docs.

1 Like