8

If I have these two collections:

Book: {
title: String,
description: String
author: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
}

User: {
_id: (generated by mongo)
username: String
}

And I want to index Book for FTS. Can I do it in such a way that it will also be searchable by username even though the usernames are not explicitly stored in the books collection?

In other words, is it possible (or advisable) to index a populated collection?

Thanks

Michael Seltenreich
  • 3,013
  • 2
  • 29
  • 55
  • refer to these: http://stackoverflow.com/questions/13026486/how-to-populate-a-sub-document-in-mongoose-after-creating-it http://mongoosejs.com/docs/api.html#model_Model.populate – Rahul Changlani Dec 30 '15 at 11:45
  • So by adding index:true, the reference will become indexed within the collection? – Michael Seltenreich Dec 30 '15 at 11:47
  • 4
    No. It is not possible to do any kind of search ( FTS or otherwise ) on data contained on "username" ( or any other field ) from another collection. This is a "join", which is something MongoDB does not do ( excluding aggregation `$lookup` ), and "populate" is not really a join, but just a convenience wrapper around running separate lookup queries. You can only ever ask the database to search on data from one collection only at a time. – Blakes Seven Dec 30 '15 at 12:03
  • Okay. Thank you for the clear answer! – Michael Seltenreich Dec 30 '15 at 12:17

1 Answers1

1

As Blakes Seven mentioned, it is not possible to index across collections.

In cases where this kind of full text search has been paramount to my application, the classic solution is to denormalize the field and included it in both collections. In this case, your Book collection would look like:

Book: {
  title: String,
  description: String
  author: {
    type: mongoose.Schema.Types.ObjectId, 
    ref: 'User',
    ### New field ###
    username: String
  },
}

Now you can index on author.username.

It is entirely dependent on your application whether or not that is a good idea. Downsides include synchronizing username across collections and adding unnecessary weight to each document.

tyleha
  • 3,319
  • 1
  • 17
  • 25