I have 2 collections in mongodb
Clothes and Colors
Clothes:
[
{ "name": "t-shirt" },
{ "name": "pants" }
]
Colors:
[
{ "color": "yellow" },
{ "color": "red" }
]
I want to have multiply of 2 collections in result
[
{ "name": "t-shirt", "color": "red" },
{ "name": "t-shirt", "color": "yellow" },
{ "name": "pants", "color": "red" },
{ "name": "pants", "color": "yellow" }
]
How can I do this? Thx!
Query
lookup without any criteria (all with all)
unwind
project to fix the structure to get the expected output
Playmongo
clothes.aggregate(
[{"$lookup": {"from": "Colors", "pipeline": [], "as": "results"}},
{"$unwind": "$results"},
{"$project": {"_id": 0, "name": 1, "color": "$results.color"}}])
Related
Desired Behavior:
Delete a property from each object in an array of objects in all documents in a collection.
What I've Tried:
The docs show $unset is used for deleting object properties:
db.products.update(
{ sku: "unknown" },
{ $unset: { quantity: "", instock: "" } }
)
Another post gives an example of how to delete a nested property in multiple documents:
db.collectionName.update(
{ },
{ "$unset": { "values.727920": "" } },
{ "multi":true }
)
Source: https://stackoverflow.com/a/31384375
I had a look at:
https://docs.mongodb.com/manual/reference/operator/update/positional-all/
https://docs.mongodb.com/manual/reference/operator/update/positional-all/#positional-update-all
which gave the example:
db.students.update(
{ },
{ $inc: { "grades.$[]": 10 } },
{ multi: true }
)
So I tried the following and it seems to work:
db.my_collection.update(
{ },
{ "$unset" : { "array_of_objects.$[].weight": "" } },
{ "multi" : true }
)
Question:
Is this the correct way to:
delete each weight property in each object in array_of_objects in
all documents
Schema:
{
"_id": ObjectId("5d1d85aa00341124bc90d158"),
"title": "hello 01",
"array_of_objects": [
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
},
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
},
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
}]
},
{
"_id": ObjectId("5d1d85aa11341124bc90d158"),
"title": "hello 02",
"array_of_objects": [
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
},
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
},
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
}]
},
{
"_id": ObjectId("5d1d85aa22341124bc90d158"),
"title": "hello 03",
"array_of_objects": [
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
},
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
},
{
"color": "blue",
"weight": "100",
"date": "2019-07-04T11:12:59.356Z"
}]
}
I am working on Mongodb distinct query, i have one collection with repeated entry, i am doing as per the created_at. But i want to fetch without repeated values.
Sample JSON
{
"posts": [{
"id": "580a2eb915a0161010c2a562",
"name": "\"Ah Me Joy\" Porter",
"created_at": "15-10-2016"
}, {
"id": "580a2eb915a0161010c2a562",
"name": "\"Ah Me Joy\" Porter",
"created_at": "25-10-2016"
}, {
"id": "580a2eb915a0161010c2a562",
"name": "\"Ah Me Joy\" Porter",
"created_at": "01-10-2016"
}, {
"id": "580a2eb915a0161010c2bf572",
"name": "Hello All",
"created_at": "05-10-2016"
}]
}
Mongodb Query
db.getCollection('posts').find({"id" : ObjectId("580a2eb915a0161010c2a562")})
So i want to know about distinct query of mongodb, please kindly go through my post and let me know.
try as follows:
db.getCollection('posts').distinct("id")
It will return all the unique IDs in the collection posts as follows:
["580a2eb915a0161010c2a562", "580a2eb915a0161010c2bf572"]
From MongoDB docs:
The example use the inventory collection that contains the following documents:
{ "_id": 1, "dept": "A", "item": { "sku": "111", "color": "red" }, "sizes": [ "S", "M" ] }
{ "_id": 2, "dept": "A", "item": { "sku": "111", "color": "blue" }, "sizes": [ "M", "L" ] }
{ "_id": 3, "dept": "B", "item": { "sku": "222", "color": "blue" }, "sizes": "S" }
{ "_id": 4, "dept": "A", "item": { "sku": "333", "color": "black" }, "sizes": [ "S" ] }
To Return Distinct Values for a Field (dept):
db.inventory.distinct( "dept" )
The method returns the following array of distinct dept values:
[ "A", "B" ]
Reference:
https://docs.mongodb.com/v3.2/reference/method/db.collection.distinct/
As per my understanding, you want to get distinct results which should eliminates the duplicate id in that collection
By using distinct in mongodb, It will return list of distinct values
db.getCollection('posts').distinct("id");
["580a2eb915a0161010c2a562", "580a2eb915a0161010c2bf572"]
So you should look into mongodb aggregation
db.posts.aggregate(
{ "$group" : { "_id" : "$id", "name" : {"$first" : "$name"}, "created_at" : {"$first" : "$created_at"} }}
)
The output will be list of results which eliminates the duplicate id documents
We have an index of Users e.g.
{
"name": "Eli",
"cars": [
{ "model": "Honda", "color": "Red" },
{ "model": "Honda", "color": "Blue" },
{ "model": "Toyota", "color": "Red" }
]
}
{
"name": "Don",
"cars": [
{ "model": "Honda", "color": "Blue" },
{ "model": "Honda", "color": "Black" },
{ "model": "Toyota", "color": "Red" }
]
}
We are trying to retrieve all the users with a Red Honda, but we couldn't find a way to do it in ElasticSearch
Since i dont know which elasticsearch version you are using, i'm referencing to the current.
What you are looking at is the following:
https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-objects.html
and
https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-mapping.html
and
https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-query.html
with the nested mapping you can create a query like the following:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "cars",
"query": {
"bool": {
"must": [
{
"term": {
"cars.model": "honda"
}
},
{
"term": {
"cars.color": "red"
}
}
]
}
}
}
}
]
}
}
}
link to example: https://www.found.no/play/gist/91c5a6c8c9fe81928b1cc497f8740a3f
(click run)
Be aware, this is only working when you are working with nested objects! The mapping must know this.
I want to modify scoring in ElasticSearch (v2+) based on the weight of a field in a nested object within an array.
For instance, using this data:
PUT index/test/0
{
"name": "red bell pepper",
"words": [
{"text": "pepper", "weight": 20},
{"text": "bell","weight": 10},
{"text": "red","weight": 5}
]
}
PUT index/test/1
{
"name": "hot red pepper",
"words": [
{"text": "pepper", "weight": 15},
{"text": "hot","weight": 11},
{"text": "red","weight": 5}
]
}
I want a query like {"words.text": "red pepper"} which would rank "red bell pepper" above "hot red pepper".
The way I am thinking about this problem is "first match the 'text' field, then modify scoring based on the 'weight' field". Unfortunately I don't know how to achieve this, if it's even possible, or if I have the right approach for something like this.
If proposing alternative approach, please try and keep a generalized idea where there are tons of different similar cases (eg: simply modifying the "red bell pepper" document score to be higher isn't really a suitable alternative).
The approach you have in mind is feasible. It can be achieved via function score in a nested query .
An example implementation is shown below :
PUT test
PUT test/test/_mapping
{
"properties": {
"name": {
"type": "string"
},
"words": {
"type": "nested",
"properties": {
"text": {
"type": "string"
},
"weight": {
"type": "long"
}
}
}
}
}
PUT test/test/0
{
"name": "red bell pepper",
"words": [
{"text": "pepper", "weight": 20},
{"text": "bell","weight": 10},
{"text": "red","weight": 5}
]
}
PUT test/test/1
{
"name": "hot red pepper",
"words": [
{"text": "pepper", "weight": 15},
{"text": "hot","weight": 11},
{"text": "red","weight": 5}
]
}
post test/_search
{
"query": {
"bool": {
"disable_coord": true,
"must": [
{
"match": {
"name": "red pepper"
}
}
],
"should": [
{
"nested": {
"path": "words",
"query": {
"function_score": {
"functions": [
{
"field_value_factor": {
"field" : "words.weight",
"missing": 0
}
}
],
"query": {
"match": {
"words.text": "red pepper"
}
},
"score_mode": "sum",
"boost_mode": "replace"
}
},
"score_mode": "total"
}
}
]
}
}
}
Result :
"hits": [
{
"_index": "test",
"_type": "test",
"_id": "0",
"_score": 26.030865,
"_source": {
"name": "red bell pepper",
"words": [
{
"text": "pepper",
"weight": 20
},
{
"text": "bell",
"weight": 10
},
{
"text": "red",
"weight": 5
}
]
}
},
{
"_index": "test",
"_type": "test",
"_id": "1",
"_score": 21.030865,
"_source": {
"name": "hot red pepper",
"words": [
{
"text": "pepper",
"weight": 15
},
{
"text": "hot",
"weight": 11
},
{
"text": "red",
"weight": 5
}
]
}
}
]
}
The query in a nutshell would score a document that satisfies the must clause as follows : sum up the weights of the matched nested documents with the score of the must clause.
Hey im trying some aggregation on mongodb using moongose:
I got this data:
[
{
"school": "1",
"preferences": [
{
"person": "X",
"color": "A"
},
{
"person": "X",
"color": "B"
},
{
"person": "Y",
"color": "A"
}
]
},
{
"school": "2",
"preferences": [
{
"person": "Z",
"color": "A"
},
{
"person": "Y",
"color": "C"
}
]
}
]
I think the data explaisn it self, What i want to get as result is,
when i query for the school that matches '1'. i would like to get this result:
[
{
"_id": "X",
"colors": [
"A",
"B"
]
},
{
"_id": "Y",
"colors": ["A"]
}
]
I used aggregation before, but i cant figure to get this result.
Check this aggregation query :
db.collectionName.aggregate({
"$match": {
"school": "1"
}
}, {
"$unwind": "$preferences"
}, {
"$group": {
"_id": "$preferences.person",
"colors": {
"$addToSet": "$preferences.color" // $addToSet used here only to add distinct color
}
}
})
Edit If you want count the number of color then used group with sum as below :
db.collectionName.aggregate({
"$match": {
"school": "1"
}
}, {
"$unwind": "$preferences"
}, {
"$group": {
"_id": "$preferences.color",
"appears": {
"$sum": 1
}
}
})
EDIT
As per your new requirement you should do following aggregation:
db.collectionName.aggregate({
"$unwind": "$preferences"
},
{
"$group": {
"_id": {
"person": "$preferences.person",
"color": "$preferences.color"
},
"count": {
"$sum": 1
}
}
},
{
"$group": {
"_id": "$_id.person",
"colors": {
"$push": {
"color": "$_id.color",
"count": "$count"
}
}
}
},
{
"$project": {
"_id": 0,
"person": "$_id",
"colors": 1
}
}).pretty()