How to Search in Array of Object in Mongodb

How to search in array of object in mongodb

The right way is:

db.users.find({awards: {$elemMatch: {award:'National Medal', year:1975}}})

$elemMatch allows you to match more than one component within the same array element.

Without $elemMatch mongo will look for users with National Medal in some year and some award in the year 1975, but not for users with National Medal in 1975.

See MongoDB $elemMatch Documentation for more info. See Read Operations Documentation for more information about querying documents with arrays.

How get query for array of objects in Mongodb?

You can use the $ keyword.
This will allow you to perform queries on all the elements in an inner array.

For example: db.collection.find({'users.assigned.$.status': 'active'})

Search for an object with a specific value in an array in MongoDB

You can query embedded documents inside an array using find as below:

db.collection.find({"tracking.track_id": "abcd"})

Playground

Retrieve only the queried element in an object array in MongoDB collection

MongoDB 2.2's new $elemMatch projection operator provides another way to alter the returned document to contain only the first matched shapes element:

db.test.find(
{"shapes.color": "red"},
{_id: 0, shapes: {$elemMatch: {color: "red"}}});

Returns:

{"shapes" : [{"shape": "circle", "color": "red"}]}

In 2.2 you can also do this using the $ projection operator, where the $ in a projection object field name represents the index of the field's first matching array element from the query. The following returns the same results as above:

db.test.find({"shapes.color": "red"}, {_id: 0, 'shapes.$': 1});

MongoDB 3.2 Update

Starting with the 3.2 release, you can use the new $filter aggregation operator to filter an array during projection, which has the benefit of including all matches, instead of just the first one.

db.test.aggregate([
// Get just the docs that contain a shapes element where color is 'red'
{$match: {'shapes.color': 'red'}},
{$project: {
shapes: {$filter: {
input: '$shapes',
as: 'shape',
cond: {$eq: ['$$shape.color', 'red']}
}},
_id: 0
}}
])

Results:

[ 
{
"shapes" : [
{
"shape" : "circle",
"color" : "red"
}
]
}
]

Search MongoDB Array of Objects in any order

You can use the $all operator:

db.collection.find(
{
field1: "TEST",
field2: {
$all: [
{ "index": "A", "value": "1" },
{ "index": "B", "value": "2" },
{ "index": "C", "value": "3" }
]
}
}
)

MongoDB Full Text Search in an Array of objects

There are a couple of ways you could handle it. If you want to return only the matching documents, it's a little more complicated.

I assume you want to return only the matched items. In order to do so you will need to use the aggregation pipeline, specifically the $unwind and $match operators.

Check out a live demo here

Consider the following:

Database

[
{
_id: ObjectId("111111111111111111111111"),
images: [
{
id: ObjectId("123123224454323123121314"),
name: "foo",
url: "cdn.domain.com/images/foo",
topic: "lorem ipsum"
},
{
id: ObjectId("222123224454323123121314"),
name: "bar",
url: "cdn.domain.com/images/bar",
topic: "lorem ipsum"
},
{
id: ObjectId("333323224454323123121314"),
name: "baz",
url: "cdn.domain.com/images/baz",
topic: "lorem ipsum"
}
]
},
{
_id: ObjectId("222222222222222222222222"),
images: [
{
id: ObjectId("888823224454323123121314"),
name: "text",
url: "cdn.domain.com/images/text",
topic: "lorem ipsum"
},
{
id: ObjectId("999993224454323123121314"),
name: "foo",
url: "cdn.domain.com/images/pic",
topic: "lorem ipsum"
}
]
}
]

Query

db.collection.aggregate([
{
$unwind: "$images"
},
{
$match: {
"images.name": "foo" // <-- replace "foo" with your query
}
}
])

Result

[
{
"_id": ObjectId("111111111111111111111111"),
"images": {
"id": ObjectId("123123224454323123121314"),
"name": "foo",
"topic": "lorem ipsum",
"url": "cdn.domain.com/images/foo"
}
},
{
"_id": ObjectId("222222222222222222222222"),
"images": {
"id": ObjectId("999993224454323123121314"),
"name": "foo",
"topic": "lorem ipsum",
"url": "cdn.domain.com/images/pic"
}
}
]

Update

To include regex.

Live demo

Query

db.collection.aggregate([
{
$unwind: "$images"
},
{
$match: {
"images.name": {
"$regex": "fo*"
}
}
}
])

Filter and find documents which have more than one element in an array of objects which have same key value pair - mongodb

  1. $expr - Allow using aggregation operator.

    1.1. $gt - Filter the document with the result of 1.1.1 greater than 1.

    1.1.1. $size - Get the size of the result 1.1.1.1.

    1.1.1.1. $filter - Filter the document(s) with type: 1 in usersArray.

db.collection.find({
$expr: {
$gt: [
{
$size: {
$filter: {
input: "$usersArray",
cond: {
$eq: [
"$$this.type",
1
]
}
}
}
},
1
]
}
})

Sample Mongo Playground


In case usersArray is possibly null or not array, then you need to check the usersArray is an array, else assign an empty array via $cond and $isArray.

db.collection.find({
$expr: {
$gt: [
{
$size: {
$filter: {
input: {
$cond: {
if: {
$isArray: "$usersArray"
},
then: "$usersArray",
else: []
}
},
cond: {
$eq: [
"$$this.type",
1
]
}
}
}
},
1
]
}
})

Sample Mongo Playground (With check array)

MongoDB $lookup on array of objects with reference objectId

Here, to make it more clear take a look at Mongo playground

db.Orders.aggregate([
{
$unwind: "$promotionsDetails.promotionsData"
},
{
"$lookup": {
"from": "Company",
"localField": "promotionsDetails.promotionsData.companyId",
"foreignField": "_id",
"as": "promotionsDetails.promotionsData.companyData"
}
},

])

MongoDB query IN array of object

This can not be done with a simple query. You will have to loop over employees.departments and for each iteration add its departments_id to an array. This array you then can use in your second line. This is something best done in your language of choice.

In order to make this easier, you'll have to change your schema. One option is to
store the department information in the employee record, but in your case you'd be duplicating a lot of data.

I would instead suggest to have each department contain a list with employee IDs and dates instead like this:

{
"_id" : ObjectId("4f9643957f8b9a3f0a000004"),
"dept_name" : "Marketing",
"managers" : [
]
"employees" : [
{
"employee_id" : ObjectId("4f9643967f8b9a3f0a00005a"),
"from_date" : "1990-01-03",
"to_date" : "1990-01-15"
}
]
}

In that case, you can then simply run:

db.departments.find( { "employees.employee_id": ObjectId("some_id") } );


Related Topics



Leave a reply



Submit