spacecat
spacecat

Reputation: 148

query all fields of a MongoDB document

import pymongo

client = pymongo.MongoClient(host='localhost', port=27017)
db = client['db']
collection = db['foo']

data = [{           # doc 1

        'foo': 'x',
        'bar': 'y',
        'baz': 'z'

        },

        {
                    # doc 2
        'foo': 'a',
        'bar': 'b',
        'baz': 'c'

        },

        {           # doc 3

        'foo': 'd',
        'bar': 'a',
        'baz': 'e'

        }]

result = collection.insert_many(data)

I'm looking for a way to query the collection for the value 'a' without having to specify the field. Ideally it would be something like...

cursor = collection.find({'*': 'a'})

...where '*' means that all fields should be queried and documents 2 and 3 in the above example code should be returned.

I can work around this, but I'm hoping there's a way to do it purely with Mongo commands to keep my code concise. I have looked through Mongo's documentation but can only query examples that match specific fields, not any field.

Upvotes: 1

Views: 5478

Answers (2)

prasad_
prasad_

Reputation: 14287

This solution uses text search functionality. This requires creating a compound index on all the fields that are to be searched as a text index. In the example collection, below, the fields fld1, fld2, fld3 of the collection srch3.

1. Sample collection:

{ _id: 1, fld1: "app", fld2: "ban", fld3: "pin" },
{ _id: 2, fld1: "gua", fld2: "ora", fld3: "kiw" },
{ _id: 3, fld1: "man", fld2: "ban", fld3: "pin" },
{ _id: 4, fld1: "pom", fld2: "lit", fld3: "fig" },
{ _id: 5, fld1: "app", fld2: "cus", fld3: "ora" }

2. Create text index:

db.srch3.createIndex( { fld1: "text", fld2: "text", fld3: "text" } )

3. Query:

db.srch3.find( { $text: { $search: "ora" } } )

Returns documents with _id's 2 and 5.

db.srch3.find( { $text: { $search: "cus" } } )

Returns document with _id = 5

db.srch3.find( { $text: { $search: "ban" } } )

Returns documents with _id's 3 and 1.

db.srch3.find( { $text: { $search: "gas" } } )

No documents are matched.



SOLUTION #2

This is a workaround solution. Create a dummy additional field with an array of all the field values for each document in the collection; e.g., foo_bar_baz as in the example below. Query on this new field.

{ _id: 1,
   'foo':'x',
   'bar':'y',
   'baz':'z',
   'foo_bar_baz': [ 'x', 'y', 'z' ]
},
{ _id: 2,
   'foo':'a',
   'bar':'b',
   'baz':'c',
   'foo_bar_baz': [ 'a', 'b', 'c' ]
},
{ _id: 3,
   'foo':'d',
   'bar':'a',
   'baz':'e',
   'foo_bar_baz': [ 'd', 'a', 'e' ]
}


Query:

db.srch1.find( { foo_bar_baz: 'a' } )

The query returns the two documents with the _id values 2 and 3.

NOTE: This will require the application keep the field values with the foo_bar_baz field in sync.

Upvotes: 0

jstuartmilne
jstuartmilne

Reputation: 4488

So I think you need an index to do that : https://docs.mongodb.com/manual/core/index-text/

After creating an index :

db.collection.createIndex( { "$**": "text" } ) #taken from docs

You can search it like this

cursor = collection.find({ $text: { $search: 'stringYouAreLookingFor' } });

Hope it helps

Upvotes: 1

Related Questions