New and confused using search

If I have a collection, which Im using mongoose.js and node.js, I created all the data in the collections so I can test and learn. When I added new documents that only differ in the value of the property guildId. I am trying to only return documents that match the guildId and roleName. I was surprised when the first results’ guildId didnt match. I have been trying to figure this out, Ive read the docs and watched the videos but I feel like Im missing something.


const pipelineName = [
			{
				$search: {
					index: 'role_name',
					compound: {
						must: [
							{
								text: {
									query: guildId,
									path: 'guildId',
								},

								text: {
									query: findRole.name,
									path: {
										wildcard: '*',
									},
									synonyms: 'aliases',
								},
							},
						],
					},
				},
			},
			{
				$project: {
					guildId: 1,
					roleId: 1,
					roleType: 1,
					roleName: 1,
					aliases: 1,
					dependencies: 1,
				},
			},
		];

This is my search index for the above query:

{
  "analyzer": "lucene.english",
  "searchAnalyzer": "lucene.english",
  "mappings": {
    "dynamic": false,
    "fields": {
      "roleName": {
        "analyzer": "syn",
        "searchAnalyzer": "syn",
        "type": "string"
      }
    }
  },
  "analyzers": [
    {
      "charFilters": [],
      "name": "syn",
      "tokenFilters": [
        {
          "type": "lowercase"
        }
      ],
      "tokenizer": {
        "type": "whitespace"
      }
    }
  ],
  "synonyms": [
    {
      "analyzer": "syn",
      "name": "aliases",
      "source": {
        "collection": "aliases"
      }
    }
  ]
}

I have synonyms setup on the roleName field which is a string and the guildId field is also a string

I adjust my aggregate to include a $match, and that seems to work:

const pipelineName = [
			{
				$search: {
					index: 'role_name',
					compound: {
						must: [
							{
								text: {
									query: findRole.name,
									path: 'roleName',
									synonyms: 'aliases',
								},
							},
						],
					},
				},
			},
			{
				$match: {
					guildId: guildId,
				},
			},
			{
				$project: {
					guildId: 1,
					roleId: 1,
					roleType: 1,
					roleName: 1,
					aliases: 1,
					dependencies: 1,
				},
			},
		];

Hi @Human_N_A,

Maybe using filter might help here. However, can you give some sample documents and the expected output (or output you achieved using the $match stage)? Interested to see the data type of the guildId field.

To clarify, do you mean the documents where you specified the below text operator did not return any documents?:

  "text": {
    "query":"guildId",
    "path":"guildId"
  }

You may find the data types documentation in regards to Atlas search useful as well.

Regards,
Jason

Thank you for the response! It would return two documents, as I had two docs with the same roleName but only one doc matched the guildId, I incorrectly assumed since I used $must that it would only return if there was a match to both.

Both fields are used as Strings.

I’ll have to read up on filter and data types again, so much still to learn!

1 Like

Thanks for clarification @Human_N_A :slight_smile: - For what it’s worth, the filter documentation linked in my previous response has an example where it replaces a $match stage – You can also check out the $match Aggregation Stage Usage documentation with regards to Atlas Search performance as this may be helpful as well.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.