Locate identical values within an array in MongoDB, even if they exist independently of an object

{
    "_id" : ObjectId("15672"),
    "userName" : "4567",
    "library" : [ 
        {
            "serialNumber" : "Book_1"
        }, 
        {
            "serialNumber" : "Book_2"
        }, 
        {
            "serialNumber" : "Book_4"
        }
    ]
},
{
    "_id" : ObjectId("123456"),
    "userName" : "123",
    "library" : [ 
        {
            "serialNumber" : "Book_2"
        }
    ]
},
{
    "_id" : ObjectId("1835242"),
    "userName" : "13526",
    "library" : [ 
        {
            "serialNumber" : "Book_7"
        }, 
        {
            "serialNumber" : "Book_6"
        }, 
        {
            "serialNumber" : "Book_5"
        }, 
        {
            "serialNumber" : "Book_4"
        }, 
        {
            "serialNumber" : "Book_3"
        }, 
        {
            "serialNumber" : "Book_5"
        }
    ]
}

I need assistance with a query that can identify usernames where duplicate serial numbers exist across libraries, excluding one specific username's library from the comparison.

Answer №1

Give this query a shot:

db.collection.aggregate([
    /** You can optionally include the first match stage if all your documents are arrays and not empty */
    { $match: { $expr: { $and: [{ $eq: [{ $type: "$library" }, "array"] }, { $ne: ["$library", []] }] } } },
    /** Create a new field 'allUnique' in each document, which will be false if there are duplicates within the 'library' elements */
    {
        $addFields: {
            allUnique: {
                $eq: [
                    {
                        $size:
                        {
                            $reduce: {
                                input: "$library.serialNumber",
                                initialValue: [], // start with an empty array
                                /** Iterate over the serialNumber's array from library and add current value only if it's unique, resulting in an array of unique values */
                                in: { $cond: [{ $in: ["$$this", "$$value"] }, [], { $concatArrays: [["$$this"], "$$value"] }] }
                            }
                        }
                    },
                    {
                        $size: "$library"
                    }
                ]
            }
        }
    },
    /** Get documents where allUnique is false */
    {
        $match: {
            allUnique: false
        }
    },
    /** Project only required fields and remove the default _id projection */
    {
        $project: {
            userName: 1,
            _id: 0
        }
    }
])

Another approach could involve using $unwind, but this may not be ideal for large datasets as it can significantly increase the size of your collection.

Test it out: MongoDB-Playground

You can also refer to @Dennis's answer in this thread on removing duplicate entries from an array for another method:

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $and: [
          {
            $eq: [
              {
                $type: "$library"
              },
              "array"
            ]
          },
          {
            $ne: [
              "$library",
              []
            ]
          }
        ]
      }
    }
  },
  {
    $addFields: {
      allUnique: {
        $eq: [
          {
            $size: {
              "$setUnion": [
                "$library.serialNumber",
                []
              ]
            }
          },
          {
            $size: "$library"
          }
        ]
      }
    }
  },
  {
    $match: {
      allUnique: false
    }
  },
  {
    $project: {
      userName: 1,
      _id: 0
    }
  }
])

Test it here: MongoDB-Playground

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering errors while attempting to share files in a system built with Node.js, Express,

This snippet shows my Node.js code for connecting to a database using Mongoose const mongoose = require('mongoose'); function connectDB() { // Establishing Database connection mongoose.connect(process see your Naughty's you're sure ...

Retrieve the duplicated items from an array by comparing two specific properties in JavaScript

I need assistance in identifying and retrieving duplicate objects within an array that share similarities in 2 specific properties. Consider the object structure below: let arry = [ {Level: "A-1", Status: "approved"}, {Level: &q ...

Adding two double arrays together using AVX vectorization technique

I'm looking for a way to add the elements of two double arrays together and store the result in a third array. Currently, I have the following simplified function: void add( double* result, const double* a, const double* b, size_t size) { memcpy( ...

Is it necessary to utilize Babel with Node.js?

I am aware that Node.js fully supports ES6 now, using version 7.2.1. Recently, I was advised by someone that the current ES6 implementation in Node.js may not be production ready and that I might need to use Babel for a more robust ES6 set-up. After visit ...

Unable to trigger click event on dynamically added element using Chrome (jQuery)

My approach here involves dynamically creating a drop-down and binding the click event to the <option> within the <select> var $select = $('<select></select>'), $option1 = $('<option>a</option>') ...

Using Jquery's $.each() method within an ajax call can be a powerful

Is it possible for a jQuery each loop to wait for Ajax success before continuing when sending SMS to recipients from an object? I want my script to effectively send one SMS, display a success message on the DOM, and then proceed with the next recipient. O ...

What is the best method for retaining the complete YQL outcome within a JavaScript object?

I am trying to store the output of my YQL Query in a JavaScript object Here is my query: SELECT * FROM html WHERE url="http://myurl.com" and xpath="/html/body/center/table[1]/tr" Can someone guide me on how to proceed? I have gone through the YQL docu ...

Adding elements to an array of unsigned 8-bit integers

I'm a beginner in C++, and I'm encountering an issue when trying to insert an element into a uint8_t array. The error message I'm getting is displayed below. I would appreciate any help in resolving this problem. Error main.cpp: In function ...

Optional subscripting for arrays in Swift allows for safe and concise

Here is a simple playground code snippet: var array :[Int?] array = [1, 2, 3] array![1] = 4 Encountered an error while running the Playground Playground execution failed: error: :8:1: error: '@lvalue $T6' is not identical to 'Int?' ...

Do we still need to configure XSRF-TOKEN on the server even when using HttpClientXsrfModule?

Would implementing the code below in app.module be sufficient to protect against XSRF/CSRF on the client side? HttpClientXsrfModule.withOptions({ cookieName: 'XSRF-TOKEN', headerName: 'X-XSRF-TOKEN' }) Alternatively, is additional ...

obtaining pictures from information obtained in vuejs

Trying to showcase images in my code that are already stored in my data like this: <div > <tr v-for='(ships,index) in destroyedShipBox' :key='index'> <td>{{ships}}</td> ...

Can the useEffect hook prevent the page from rendering?

Is there a way to have a slight delay every time the user visits or reloads the page in order to allow for content loading? Currently, I am using a useEffect() with a setTimeout() function that sets the variable isLoading to false after 1 second. However, ...

Delving into the intricacies of Promises/A+ and the mechanics of Asynchronicity in Javascript

I am new to JavaScript programming and may have some questions that seem basic. I was recently following a tutorial on Spring Boot and React. The author used a library called "rest" (package.json - "rest": "^1.3.1") and mentioned it is a Promises/A+ based ...

Limit express to only allow AJAX requests

Currently working on an Express app where I aim to restrict access to the routes exclusively through AJAX requests. Aware that this involves using the X-Requested-With header, but uncertain of how to globally block other request types. Any suggestions or ...

The issue with Multiselect arises when the array is being set up initially

Using primeng Multiselect, I have implemented a logic to push data based on search value from the backend. To avoid the error of pushing undefined elements, initialization is required before pushing. However, when I initialize the dropdown's array var ...

Mobile page sliding mechanism

My website contains a div that is mostly off the page, but on hover it translates onto the main page. You can check out my website. However, this method doesn't work well on mobile devices. Hovering is not effective and I often have to click multipl ...

Retrieve the processed data from a file using node.js

I have successfully read and parsed my file, however I am facing an issue with retrieving the output string. I want to access this string from a variable assigned to it on the client side. Despite using async series to handle callback functions effective ...

"Patience is key when waiting for an AJAX response within a jQuery loop

I've been facing difficulties in making this work using the $.Deferred object. Here is a simplified version of the code setup. g_plans = []; $(function(){ // Need to utilize a custom ajax function that returns a promise object var pageLoadPro ...

combining arrays from two collections in MongoDB

In my database, I have two collections: Clinics and Doctors. Clinics can have multiple Doctors. The relationship between them was established as follows: doctor: [{ doctorId: { type: mongoose.Schema.Types.ObjectId, ref: 'doctors&apos ...

Modify the text of a button depending on the condition and user interaction within an ng-repeat loop in AngularJS

I have a scenario where I am displaying a list of users with two buttons for Start and End using the ng-repeat code: <div class="list-group" ng-repeat="patient in patients" > <a href="#" class="list-group-item" ng-click="chat ...