4

I'm using the aggregate method in Mongodb against a text search. I've tried various way with this and still can't find the correct way to filter my results. I've setup an index and it works fine with just the $text search and also works fine with just the query.

Here's my code to do a text search:

Model.aggregate([
    { $match: { $text: { $search: searchValue } } },
    { $project: { displayTitle: 1, title: 1, body: 1, _type: 1, _id: 1, score: { $meta: "textScore" } } },
    { $match: { score: { $gt: 1.0 } } }
], function (err, models) {

})

However I want to be able to filter the models further by this query:

Model.find({_parentIds: {$in: arrayOfIds}})

I would have thought that this would work:

Model.aggregate([
    { $match: { $text: { $search: searchValue }, _parentIds: {$in: arrayOfIds} } },
    { $project: { displayTitle: 1, title: 1, body: 1, _type: 1, _id: 1, score: { $meta: "textScore" } } },
    { $match: { score: { $gt: 1.0 } } }
])

But sadly it doesn't. Has anyone tried this or am I missing something?

Here's an example collection I'm searching through:

[{
    displayTitle: "first item",
    title: "first_item",
    _type: "item",
    _parentIds: ["123", "234"]
}, {
    displayTitle: "second item",
    title: "second_item",
    _type: "item",
    _parentIds: ["123", "234"]
}, {
    displayTitle: "third item",
    title: "third_item",
    _type: "item",
    _parentIds: ["345", "456"]
}]

My current search would be something like this:

searchValue = "item"
arrayOfIds = ["345"];

and would be expecting this document only back:

{
    displayTitle: "third item",
    title: "third_item",
    _type: "item",
    _parentIds: ["345", "456"]
}

Thanks!

darylhedley
  • 258
  • 1
  • 8
  • 23

1 Answers1

5

The text score is 0.75. So changing match filter to greater than 0.5 works.

Modified projection to exclude the body, _id and include parent ids.

Created index with this query.

db.textcol.createIndex( { displayTitle: "text" } )

Running this query.

db.textcol.aggregate([
    { $match: { $text: { $search: "item" }, _parentIds: {$in: ["345"]} }} ,
    { $project: { displayTitle: 1, title: 1, _type: 1, _id: 0, _parentIds :1, score: { $meta: "textScore" } }},
        { $match: { score: { $gt: 0.5 } } }
])

Output:

{
    "displayTitle": "third item",
    "title": "third_item",
    "_type": "item",
    "_parentIds": ["345", "456"],
    "score": 0.75
}
s7vr
  • 73,656
  • 11
  • 106
  • 127
  • Thank you!!! This saved me! So, my actual problem which I should have been a bit more clearer about was it returned results I didn't want to (so models that didn't have the _parentId in the _parentIds array). The solution above fixed it and the main reason was the _parentIds:1 and _id: 0 in the $projectand the $match of the score was too high - not sure how I didn't see that... – darylhedley Nov 05 '16 at 08:03