Subscription with $or does not return all the documents it should

I have a subscription like so: Posts.find( { $or: [ {_id: postID}, {target: postID}, {replies: postID} ] }). It does not return all the posts it should. Most notably, it does not always return the post with {_id: postID}. There are no errors on either server or client, and everything I read says this should work? The only thing I can think of is the fact that replies is an array. But as far as I can tell, that’s supposed to work too. :confused:

Edit: I tried removing the {replies: postID} clause to see if that changed anything. It didn’t. So I’m guessing it’s not that. I see in the MongoDB page for $or it says something about indexes? So maybe I don’t have those set up properly? :confused:

Are all your id’s (_id, target, replies) all of the same type (string or MongoID)? If you are mixing types, that may explain your issue. For example, it’s common for non-Meteor applications to create documents with _ids that are of type MongoID, whereas Meteor normally uses strings.

You should definitely set up your indexes properly, although missing indexes will affect performance, not functionality.

target and replies.$ are {
type: String,
regEx: SimpleSchema.RegEx.Id
}, while _id uses the default system.

As for setting up indexes, how do I go about that? I didn’t even know that was a thing. Do I use rawCollection or rawDatabase, and work with that object? Is there a tutorial or documentation on this anywhere? I’m not seeing it, but then maybe I’m just not paying attention. Should I refer to the MongoDB documentation? :confused:

As in Meteor’s default system? Do you insert any documents outside of Meteor?

Setting up indexes will not fix the issue you’ve reported - it will just improve the performance of the query, especially for large collections.

Indexes may be set up from Meteor in one of two ways. In each case, you would normally add the code into the Meteor.startup block on the server (you can’t do this on the client):

someCollection._ensureIndex(indexSpecification, options);
// or
someCollection.rawCollection().createIndex(indexSpecification,options);

Where

  • indexSpecification defines the field(s) and ordering. So, a simple index may be { createDate: -1 }, which puts a reverse-sorted index on the createDate field. Similarly, a compound index may be like { createDate: -1, userName: 1 }.
  • options is optional and is documented here.

EDIT: I forgot to mention that the _id field gets an index automatically.

1 Like

I don’t think so? All of my insert code is in javascript, and just uses the “collection.insert” call. It’s possible that somewhere along the line I have it using a module that does things differently though? :confused:

Perhaps use the MongoDB shell to inspect the docs - particularly those you suspect aren’t working.

Start your app with meteor and in another window in the same application folder, type meteor mongo. From there you can use any MongoDB shell command, for example db.posts.find().pretty().

Huh, gotcha. I’ll try that. XD