1

I tried to do this

db.users.ensureIndex({"books.title":"text", "location":"2d"})

and MongoDB refuses to create the index with this error

{
    "ok" : 0,
    "errmsg" : "bad index key pattern { books.title: \"text\", location: \"2d\" }: Can't use more than one index plugin for a single index.",
    "code" : 67
}

Is it the case that text index cannot be together with 2d index in a compound index? If so, what is the possible workaround to handle queries that are based on first books.title field and then followed by location field ?

Thank you

UPDATE :

Text index is necessary because I plan to use weighting (http://docs.mongodb.org/manual/tutorial/control-results-of-text-search/) in the near future where books.title may become books.title, books.about, and books.keywords

Regarding the query, it will be something like this

db.users.find({"books.title": "eragon", location: { $near :[ 150 , 23 ]}})

that means, find users whose location is near my point who have book entitled "eragon"

  • mongodb 2.6 now supports [index intersection](http://docs.mongodb.org/manual/core/index-intersection/), you could create a single index on `books.title` and one on `location`, although I'm not sure if it'll have the same limitation. rather than producing an error the query plan may simply ignore the second index. i'd suggest testing it out and running a `.explain()` for analysis. – zamnuts Jul 26 '14 at 07:40
  • 1
    @zamnuts Index intersection does not work with text and geo type indexes. Basic Btree indexes only are supported. But really for the poster, why do you need a "text" index here anyway? Are you possibly confusing the term here. Can a regular expression query simply not do in this case? – Neil Lunn Jul 26 '14 at 07:44
  • 1
    @NeilLunn ahh, you are correct, my bad on that. i should've tested it first instead of confirming after the fact. – zamnuts Jul 26 '14 at 07:49
  • Thanks for the answer. I need the text index because I plan to make a weighted query. For now it can actually be handled using basic index with regular expression query, but no. I need to change it to a weighted one very soon, so I need the text index. Any possible solution? – Yudho Ahmad Diponegoro Jul 26 '14 at 07:50
  • Perhaps your question should explain what you mean and need by "weighting" and also why this needs to be in combination with a location search. If you explain your use case then that may get answers. But combining geo and text indexes will not be one of them. – Neil Lunn Jul 26 '14 at 07:56
  • I have updated my question to elaborate more, @NeilLunn – Yudho Ahmad Diponegoro Jul 26 '14 at 08:05
  • 1
    @YudhoAhmadDiponegoro to use the `text` index, your query will look like `{$text:{$search:'eragon'},location:{$near:[150,23]}}`. with a text index you do not specify the specific field since everything in the index is consolidated. – zamnuts Jul 26 '14 at 08:21
  • Oh, Thank you. I will test that. I just wonder how that query will look like in MongoID. I have one question though. With that query, is it the case that we create both text index and 2d index separately, and somehow in query, they will get consolidated? – Yudho Ahmad Diponegoro Jul 26 '14 at 08:27
  • @YudhoAhmadDiponegoro different text indices are consolidated, e.g. `books.title`, `books.about` and `books.keywords` (you search all of these at the same time with `$text`). i'm not referring to indices of different types being consolidated. unless someone posts otherwise, i don't see your query utilizing multiple indices: you can only specify text and 2d separately, and these types are not available for index intersection (per @NielLunn, and my tests), thus only a single index is used. – zamnuts Jul 26 '14 at 08:32
  • aside: i wonder if two separate queries that are then intersected (inner join equiv.) in the application will perform better than a single query with only one index of text or location. – zamnuts Jul 26 '14 at 08:35
  • @zamnuts So, this `{$text:{$search:'eragon'},location:{$near:[150,23]}}` query will likely only use the "text" index and ignore the 2d index created separately, am I right? In that case, I believe I need to post this to mongodb jira as a possibly useful feature to be implemented. – Yudho Ahmad Diponegoro Jul 26 '14 at 08:39
  • 1
    @YudhoAhmadDiponegoro that is absolutely correct. i'm not sure which index will take precedence, text or location; index creation order or some sort of priority could be at play, but i am not versed in those internals. doesn't hurt to open a feature request in [SERVER](https://jira.mongodb.org/browse/SERVER) and see what they say, just takes a few minutes! – zamnuts Jul 26 '14 at 08:52
  • The mongo docs say: "You cannot combine the $near operator, which requires a special geospatial index, with a query operator or command that requires another special index. For example you cannot combine $near with the $text query." https://docs.mongodb.com/manual/reference/operator/query/near/#op._S_near – conor909 Jun 21 '17 at 21:17

1 Answers1

0

For such use cases, $geoWithin can be used instead of $near. $geoWithin can work without 2d/2dsphere index. Other index (text index) will be used to filter results based on text search and as second step $geoWithin will filter result (without index) based on location.

Rajat Goel
  • 2,207
  • 17
  • 35