Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: search contacts endpoint #33043

Merged
merged 24 commits into from
Oct 2, 2024
Merged

feat: search contacts endpoint #33043

merged 24 commits into from
Oct 2, 2024

Conversation

tapiarafael
Copy link
Member

@tapiarafael tapiarafael commented Aug 13, 2024

Proposed changes (including videos or screenshots)

Implements a new endpoint to retrieve a list of paginated contacts, allowing sorting and filtering by name, email, or phone number.

[GET] api/v1/omnichannel/contacts.search?searchText=john
response example:

{
	"contacts": [
		{
			"_id": "123",
			"name": "john doe",
			"emails": [
				"johndoe@example.com"
			],
			"phones": [
				"1-658-751-2622"
			],
			"contactManager": "321",
			"customFields": {},
			"unknown": false,
		},
	],
	"count": 25,
	"offset": 0,
	"total": 1,
	"success": true
}

Also, three indexes were created for the Contact collection to improve performance when querying for contacts. A normal index was created for name field, and partial indexes for emails and phones fields.

Explain output showing that the indexes are being used
{
  "executionSuccess": true, 
  "nReturned": new NumberInt("1"), 
  "executionTimeMillis": new NumberInt("1"),
  "totalKeysExamined": new NumberInt("158"),
  "totalDocsExamined": new NumberInt("158"),
  "executionStages": {
    "stage": "SUBPLAN",
    "nReturned": new NumberInt("1"),
    "executionTimeMillisEstimate": new NumberInt("0"),
    "works": new NumberInt("161"),
    "advanced": new NumberInt("1"),
    "needTime": new NumberInt("159"),
    "needYield": new NumberInt("0"),
    "saveState": new NumberInt("0"),
    "restoreState": new NumberInt("0"),
    "isEOF": new NumberInt("1"),
    "inputStage": {
      "stage": "OR",
      "nReturned": new NumberInt("1"),
      "executionTimeMillisEstimate": new NumberInt("0"),
      "works": new NumberInt("161"),
      "advanced": new NumberInt("1"),
      "needTime": new NumberInt("159"),
      "needYield": new NumberInt("0"),
      "saveState": new NumberInt("0"),
      "restoreState": new NumberInt("0"),
      "isEOF": new NumberInt("1"),
      "dupsTested": new NumberInt("1"),
      "dupsDropped": new NumberInt("0"),
      "inputStages": [
        {
          "stage": "FETCH", 
          "filter": {"$or": [{"name": {"$regex": "Clint", "$options": "i"}}]}, 
          "nReturned": new NumberInt("1"),
          "executionTimeMillisEstimate": new NumberInt("0"),
          "works": new NumberInt("55"),
          "advanced": new NumberInt("1"),
          "needTime": new NumberInt("53"),
          "needYield": new NumberInt("0"),
          "saveState": new NumberInt("0"),
          "restoreState": new NumberInt("0"),
          "isEOF": new NumberInt("1"),
          "docsExamined": new NumberInt("54"),
          "alreadyHasObj": new NumberInt("0"), 
          "inputStage": {
            "stage": "IXSCAN",
            "nReturned": new NumberInt("54"),
            "executionTimeMillisEstimate": new NumberInt("0"),
            "works": new NumberInt("55"),
            "advanced": new NumberInt("54"),
            "needTime": new NumberInt("0"),
            "needYield": new NumberInt("0"),
            "saveState": new NumberInt("0"),
            "restoreState": new NumberInt("0"),
            "isEOF": new NumberInt("1"),
            "keyPattern": {"name": new NumberInt("1")},
            "indexName": "name_insensitive",
            "collation": {
              "locale": "en",
              "caseLevel": false,
              "caseFirst": "off",
              "strength": new NumberInt("2"),
              "numericOrdering": false,
              "alternate": "non-ignorable",
              "maxVariable": "punct",
              "normalization": false,
              "backwards": false, "version": "57.1"
            }, 
            "isMultiKey": false,
            "multiKeyPaths": {"name": []},
            "isUnique": false,
            "isSparse": false,
            "isPartial": false,
            "indexVersion": new NumberInt("2"),
            "direction": "forward",
            "indexBounds": {"name": ["[CollationKey(0x), {})", "[/Clint/i, /Clint/i]"]},
            "keysExamined": new NumberInt("54"),
            "seeks": new NumberInt("1"),
            "dupsTested": new NumberInt("0"),
            "dupsDropped": new NumberInt("0")
          }
        },
        {
          "stage": "FETCH", 
          "filter": {"$or": [{"emails": {"$regex": "Clint", "$options": "i"}}]},
          "nReturned": new NumberInt("0"),
          "executionTimeMillisEstimate": new NumberInt("0"),
          "works": new NumberInt("53"),
          "advanced": new NumberInt("0"),
          "needTime": new NumberInt("52"),
          "needYield": new NumberInt("0"),
          "saveState": new NumberInt("0"),
          "restoreState": new NumberInt("0"),
          "isEOF": new NumberInt("1"),
          "docsExamined": new NumberInt("52"),
          "alreadyHasObj": new NumberInt("0"),
          "inputStage": {
            "stage": "IXSCAN",
            "nReturned": new NumberInt("52"),
            "executionTimeMillisEstimate": new NumberInt("0"),
            "works": new NumberInt("53"),
            "advanced": new NumberInt("52"),
            "needTime": new NumberInt("0"),
            "needYield": new NumberInt("0"),
            "saveState": new NumberInt("0"),
            "restoreState": new NumberInt("0"),
            "isEOF": new NumberInt("1"),
            "keyPattern": {"emails": new NumberInt("1")},
            "indexName": "emails_insensitive",
            "collation": {
              "locale": "en",
              "caseLevel": false,
              "caseFirst": "off",
              "strength": new NumberInt("2"),
              "numericOrdering": false,
              "alternate": "non-ignorable",
              "maxVariable": "punct",
              "normalization": false,
              "backwards": false,
              "version": "57.1"
            },
            "isMultiKey": true,
            "multiKeyPaths": {"emails": ["emails"]},
            "isUnique": false,
            "isSparse": false,
            "isPartial": true,
            "indexVersion": new NumberInt("2"),
            "direction": "forward",
            "indexBounds": {"emails": ["[CollationKey(0x), {})", "[/Clint/i, /Clint/i]"]},
            "keysExamined": new NumberInt("52"),
            "seeks": new NumberInt("1"),
            "dupsTested": new NumberInt("52"),
            "dupsDropped": new NumberInt("0")
          }
        }, 
        {
          "stage": "FETCH", 
          "filter": {"$or": [{"phones": {"$regex": "Clint", "$options": "i"}}]}, 
          "nReturned": new NumberInt("0"),
          "executionTimeMillisEstimate": new NumberInt("0"),
          "works": new NumberInt("53"),
          "advanced": new NumberInt("0"),
          "needTime": new NumberInt("52"),
          "needYield": new NumberInt("0"),
          "saveState": new NumberInt("0"),
          "restoreState": new NumberInt("0"),
          "isEOF": new NumberInt("1"),
          "docsExamined": new NumberInt("52")
          "alreadyHasObj": new NumberInt("0")
          "inputStage": {
            "stage": "IXSCAN",
            "nReturned": new NumberInt("52"),
            "executionTimeMillisEstimate": new NumberInt("0"),
            "works": new NumberInt("53"),
            "advanced": new NumberInt("52"),
            "needTime": new NumberInt("0"),
            "needYield": new NumberInt("0"),
            "saveState": new NumberInt("0"),
            "restoreState": new NumberInt("0"),
            "isEOF": new NumberInt("1"),
            "keyPattern": {"phones": new NumberInt("1")},
            "indexName": "phones_1",
            "isMultiKey": true,
            "multiKeyPaths": {"phones": ["phones"]},
            "isUnique": false,
            "isSparse": false,
            "isPartial": true,
            "indexVersion": new NumberInt("2"),
            "direction": "forward",
            "indexBounds": {"phones": ["[\"\", {})", "[/Clint/i, /Clint/i]"]},
            "keysExamined": new NumberInt("52"),
            "seeks": new NumberInt("1"),
            "dupsTested": new NumberInt("52"),
            "dupsDropped": new NumberInt("0")
          }
        }
      ]
    }
  }
}

Issue(s)

Steps to test or reproduce

Further comments

SCI-64

Copy link
Contributor

dionisio-bot bot commented Aug 13, 2024

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is targeting the wrong base branch. It should target 7.0.0, but it targets 6.14.0

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

Copy link

changeset-bot bot commented Aug 13, 2024

⚠️ No Changeset found

Latest commit: 4f4a48f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

codecov bot commented Aug 13, 2024

Codecov Report

Attention: Patch coverage is 0% with 6 lines in your changes missing coverage. Please review.

Project coverage is 58.57%. Comparing base (bcacbb1) to head (4f4a48f).
Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #33043      +/-   ##
===========================================
- Coverage    58.58%   58.57%   -0.01%     
===========================================
  Files         2737     2737              
  Lines        65757    65763       +6     
  Branches     14825    14826       +1     
===========================================
  Hits         38521    38521              
- Misses       24457    24463       +6     
  Partials      2779     2779              
Flag Coverage Δ
unit 75.66% <0.00%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

@ggazzo ggazzo force-pushed the feat/get-contact-by-id branch from 1c93671 to 81d6c87 Compare September 12, 2024 14:35
@tapiarafael tapiarafael changed the base branch from feat/get-contact-by-id to develop September 16, 2024 13:35
@tapiarafael tapiarafael changed the base branch from develop to feat/get-contact-by-id September 16, 2024 13:36
Base automatically changed from feat/get-contact-by-id to develop September 16, 2024 13:42
Copy link
Contributor

github-actions bot commented Sep 16, 2024

PR Preview Action v1.4.8
Preview removed because the pull request was closed.
2024-10-02 00:45 UTC

@tapiarafael tapiarafael changed the base branch from develop to feat/get-contact-by-id-2 September 16, 2024 19:38
@tapiarafael tapiarafael changed the base branch from feat/get-contact-by-id-2 to develop September 16, 2024 19:38
@tapiarafael tapiarafael marked this pull request as ready for review September 17, 2024 13:21
@tapiarafael tapiarafael requested review from a team as code owners September 17, 2024 13:21
Copy link
Contributor

@pierre-lehnen-rc pierre-lehnen-rc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small suggestion, not really required.

apps/meteor/app/livechat/server/lib/Contacts.ts Outdated Show resolved Hide resolved
Co-authored-by: Pierre Lehnen <55164754+pierre-lehnen-rc@users.noreply.github.com>
Copy link
Contributor

@KevLehman KevLehman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one smol request: can you put the result of the explain on the PR description so we see the indexes are doing its job? 🙏🏽

Thanks man!

apps/meteor/app/livechat/server/api/v1/contact.ts Outdated Show resolved Hide resolved
apps/meteor/server/models/raw/LivechatContacts.ts Outdated Show resolved Hide resolved
apps/meteor/tests/end-to-end/api/livechat/contacts.ts Outdated Show resolved Hide resolved
@tapiarafael tapiarafael added this to the 7.0 milestone Oct 1, 2024
@tapiarafael tapiarafael added the stat: QA assured Means it has been tested and approved by a company insider label Oct 1, 2024
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Oct 1, 2024
@kodiakhq kodiakhq bot merged commit 6208dff into develop Oct 2, 2024
50 checks passed
@kodiakhq kodiakhq bot deleted the feat/search-contacts branch October 2, 2024 00:45
abhinavkrin pushed a commit that referenced this pull request Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants