Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB Full Text on an Array within an Array of Elements

I am unable to retrieve documents when an array within an array of elements contains text that should match my search.

Here are two example documents:

{
    _id: ...,
    'foo': [
        {
            'name': 'Thing1',
            'data': {
                'text': ['X', 'X']
            }
        },{
            'name': 'Thing2',
            'data': {
                'text': ['X', 'Y']
            }
        }
    ]
}

{
    _id: ...,
    'foo': [
        {
            'name': 'Thing3',
            'data': {
                'text': ['X', 'X']
            }
        },{
            'name': 'Thing4',
            'data': {
                'text': ['X', 'Y']
            }
        }
    ]
}

By using the following query, I am able to return both documents: db.collection.find({'foo.data.text': {'$in': ['Y']}}

However, I am unable to return these results using the full text command/index: db.collection.runCommand("text", {search" "Y"})

I am certain that the full text search is working, as the same command issuing a search against "Thing1" will return the first document, and "Thing3" returns the second document.

I am certain that both foo.data.text and foo.name are both in the text index when using db.collection.getIndexes().

I created my index using: db.collection.ensureIndex({'foo.name': 'text', 'foo.data.text': 'text'}). Here are the indexes as shown by the above command:

    {
            "v" : 1,
            "key" : {
                    "_fts" : "text",
                    "_ftsx" : 1
            },
            "ns" : "testing.collection",
            "background" : true,
            "name" : "my_text_search",
            "weights" : {
                    "foo.data.text" : 1,
                    "foo.name" : 1,
            },
            "default_language" : "english",
            "language_override" : "language",
            "textIndexVersion" : 1
    }

Any suggestion on how to get this working with mongo's full text search?

like image 403
earthmeLon Avatar asked Sep 12 '13 16:09

earthmeLon


People also ask

Can MongoDB do full text search?

MongoDB offers a full-text search solution, MongoDB Atlas Search, for data hosted on MongoDB Atlas.

How do I query an array of objects in MongoDB?

To search the array of object in MongoDB, you can use $elemMatch operator. This operator allows us to search for more than one component from an array object.

How do you find documents with a matching item in an embedded array?

Use $match With $eq to Find Matching Documents in an Array in MongoDB. Use $match With $all to Find Matching Documents in an Array in MongoDB.

How do you update an array of objects in MongoDB?

Update Documents in an ArrayThe positional $ operator facilitates updates to arrays that contain embedded documents. Use the positional $ operator to access the fields in the embedded documents with the dot notation on the $ operator.


1 Answers

Text search does not currently support indexed fields of nested arrays (at least not explicitly specified ones). An index on "foo.name" works fine as it is only one array deep, but the text search will not recurse through the subarray at "foo.data.text". Note that this behavior may change in the 2.6 release.

But fear not, in the meantime nested arrays can be text-indexed, just not with individually specified fields. You may use the wildcard specifier $** to recursively index ALL string fields in your collection, i.e.

db.collection.ensureIndex({"$**": "text" }

as documented at http://docs.mongodb.org/manual/tutorial/create-text-index-on-multiple-fields/ . Be careful though as this will index EVERY string field and could have negative storage and performance consequences. The simple document structure you describe though should work fine. Hope that helps.

like image 103
jribnik Avatar answered Oct 19 '22 13:10

jribnik