0

I want to search autocomplete on the following fields :contactfirstname, contactlastname and name

Also, want to filter based on userid(s) first then perform autocomplete search

Issue: Without filter criteria, autocomplete is working fine With filter criteria in compound query not working as getting empty array

Can anyone help please?

exports.userNameCitySearchAutocomplete = async function (req, res) {
  try {
    const { userNameCityQueryparam } = req.query;
    console.log("search query param", userNameCityQueryparam);
    const agg = [
      {
        $search: {
            index: 'userNameCity',
            'compound': {
              
              "filter": [{
               "text": {
                  "query": ["6271f2bb79cd80194c81f631"],
                  "path": "_id",
                }
              }],

            "should": [
              {
              //search on user name
      
              autocomplete: {
                query: userNameCityQueryparam,
                path: 'name',
                fuzzy: {
                  maxEdits: 2,
                  prefixLength: 3
                }
              }},

              //search on user city
            
              {
                autocomplete: {
                query: userNameCityQueryparam,
                path: 'city',
                fuzzy: {
                  maxEdits: 2,
                  prefixLength: 3
                }
              },
           }
           ,

              //search on user contact first name
            
              {
                autocomplete: {
                query: userNameCityQueryparam,
                path: 'contactfirstname',
                fuzzy: {
                  maxEdits: 2,
                  prefixLength: 3
                }
              },
           }

           ,

              //search on user contact last name
            
              {
                autocomplete: {
                query: userNameCityQueryparam,
                path: 'contactlastname',
                fuzzy: {
                  maxEdits: 2,
                  prefixLength: 3
                }
              },
           }
           
          ],
            "minimumShouldMatch": 1
          }
        }
      }
    ]
    const response = await User.aggregate(agg);
    return res.json(response);
    // res.send(response);
  } catch (error) {
    console.log("autocomplete search error", error);
    return res.json([]);
  }
};

Index details in mongodb: enter image description here

{
  "mappings": {
    "dynamic": false,
    "fields": {
      "_id": {
        "type": "string"
      },
      "city": {
        "type": "autocomplete"
      },
      "contactfirstname": {
        "type": "autocomplete"
      },
      "contactlastname": {
        "type": "autocomplete"
      },
      "name": {
        "type": "autocomplete"
      }
    }
  }
}

Image of collection in mongodb enter image description here

image of empty array enter image description here

Bhol
  • 145
  • 3
  • 16

2 Answers2

0

for anyone looking for solution to this, You can use the MQL where clause in your pipeline stage definition.

{
    $match: {
      email:"email@domain.com"
    }
}

check here for an example

General Grievance
  • 4,555
  • 31
  • 31
  • 45
0
if you are using mongo atlas search would be use:
db.professionList.aggregate(
    [
    {
      $search: {
      index: "default",
      compound:{
        should:[
       { autocomplete: {
        query: "tax",
        path:"keywords" ,
        tokenOrder:"sequential"
        }},
        {autocomplete: {
          query: "tax",
          path:"name" ,
          tokenOrder:"sequential"
        }}
        ],
        minimumShouldMatch: 0 
      }
      }
    },
  {$limit:10},
  {
    $project:{
        _id:0,
        name:1,
        keywords:1,
    }
  }
]
)

*compound and should are the labels to help to use more fields in autocomplete search
"happy code and think in mongo"
ifredy3
  • 29
  • 3