147

I am using mongodb now.

I have a blogpost collection, and it has a tags field which is an array, e.g.

blogpost1.tags = ['tag1', 'tag2', 'tag3', 'tag4', 'tag5']
blogpost2.tags = ['tag2', 'tag3']
blogpost3.tags = ['tag2', 'tag3', 'tag4', 'tag5']
blogpost4.tags = ['tag1', 'tag4', 'tag5']

How can I do these search

  1. contains tag1
  2. contains ['tag1','tag2']
  3. contains any of ['tag3', 'tag4']
NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
guilin 桂林
  • 17,050
  • 29
  • 92
  • 146

2 Answers2

224

Try this out:

db.blogpost.find({ 'tags' : 'tag1'}); //1
db.blogpost.find({ 'tags' : { $all : [ 'tag1', 'tag2' ] }}); //2
db.blogpost.find({ 'tags' : { $in : [ 'tag3', 'tag4' ] }}); //3
nagle
  • 39
  • 7
Jeff the Bear
  • 5,603
  • 3
  • 22
  • 18
  • 6
    This is well documented in the help: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24all – Scott Hernandez Mar 20 '11 at 04:31
  • 2
    for the $all does it mean all elements AND in the expressed order or is it just unordered ? – redben Mar 26 '11 at 14:36
  • 2
    @ScottHernandez I do not see that they mention that the field you are using as your search can be an array, and how that is handled. "field : { $in : array }". What happens when you search for an array within an array of arrays? Not specified. – Zut Aug 14 '12 at 21:13
  • Is there any INDEXING we can do on array's to stop duplicate? If yes, please guide how. – Hitesh Joshi Sep 29 '12 at 08:56
  • @Jeff the Bear: Can you please provide the equivalent Java code? I am having great difficulty in getting the Java equivalents of these MongoDB Queries. – CodingInCircles Dec 04 '12 at 20:21
  • 1
    @redben its unordered like written in the docs: [$all operator DOCS](http://docs.mongodb.org/manual/reference/operators/#_S_all). Just read the example part and you will see. – Matthias B Jan 11 '13 at 06:46
  • @Jeff the Bear: db.blogpost.find({ 'tags' : { $in : [ /tag/ ] }}); in above query i am trying to match regex exp,when i am trying the same using node js,the variable 'tag' is creating the query like this below: db.blogpost.find({ 'tags' : { $in : [ /'78438'/ ] }}); hence it is not working but when i remove the quotes surrounding the value it works,so how to solve this problem – Pratswinz Apr 06 '16 at 04:48
5

My experience is that for (2) the following solution is much faster than the one with "$all":

db.blogpost.find({ $and: [ {tags: 'tag1'} ,{tags: 'tag2'} ] });

but to be honest, I do not not why. I would be interested in, if anyone knows.

kubudi
  • 658
  • 1
  • 9
  • 20
heinob
  • 19,127
  • 5
  • 41
  • 61
  • 1
    By the way, just tested it on indexed keywords list. Absolutely the same result with $and and $all – isox Feb 06 '13 at 13:21
  • Maybe that changed with newer versions in the meantime. – heinob Feb 06 '13 at 17:26
  • It's circumstantial. For the "$and", mongodb making a logical "and" operation. Therefore if the first expression is false, the second are not taken into consideration. This means less processing. – kubudi Mar 16 '13 at 10:49
  • But that should happen with '$all' also, shouldn't it!? – heinob Mar 16 '13 at 17:03
  • 1
    $all is probably two lookups on an index, $and is probably one lookup with a sequential scan on the result. – Evan Carroll Jun 10 '13 at 19:17