I am working in elastic search and i have following array in elastic search
{
"took": 101,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 24745,
"max_score": 1,
"hits": [
{
"_index": "users",
"_type": "user",
"_id": "742",
"_score": 1,
"_source": {
{
"id": "1",
"username": "broad",
"full_name": "Bradshaw",
"age": 29,
"gender": "Male",
"followers" : ["2","3","4"]
},
{
"id": "2",
"username": "kevin",
"full_name": "Kevin",
"age": 29,
"gender": "Male",
"followers" : ["1","3"]
},
{
"id": "3",
"username": "john",
"full_name": "John Smith",
"age": 29,
"gender": "Male",
"followers" : ["1","2"]
},
.
.
. and so on
}
]}
Now I want to delete follower two from user 1. Now I am confuse that how I do this I search user 2 but I am unable to update followers of user 1 by delete follower 2 from follower list. Can anyone tell me that what will be the query string of this problem.
Related
I have a strapi project and A flights has somr relations like drones, pilots. For example if we using postman to get a flight i send :
{
"data" : {
"Duration" : "10",
"Address" : "Address",
"account": 1,
"drone": "1",
"pilot": 1,
"User": 1,
"zone": 1,
}
}
the response is :
{
"id": 25,
"Duration" : "10",
"Address" : "Address",
"account": 1,
"drone": "1",
"pilot": 1,
"User": {
"id": 1,
"username": "AhmedMedhat",
"email": "ahmedmedhat1231#gmail.com",
"provider": "local",
"password": "$2a$10$8tkwcp73AbE0aylQyOsIdefgSiuaoOcPJzbZWxk9W2IN85SghOIjO",
"resetPasswordToken": null,
"confirmationToken": null,
"confirmed": false,
"blocked": false,
"createdAt": "2022-11-03T06:32:57.225Z",
"updatedAt": "2022-11-03T06:35:05.902Z"
},
"zone": 1,
}
only the user is populated successfully but the other relations always return null ..
maybe bec user is plugin and others is api i don't know, it works in the strapi built in routes but my customized one doesn't work .. can anyone help ??
This question already has answers here:
$lookup multiple levels without $unwind?
(1 answer)
Mongoose: deep population (populate a populated field)
(10 answers)
Closed 3 years ago.
I have a database structured like this:
I want to get all listItems, of all lists from a user with a x ID. What's the correct way of doing that?
I'm using node with mongoose, and I tried the following:
await User.findById(user._id).populate('list');
But realized that I can't populate all ListItem's from that. Meaning, I can't do this:
await User.findById(user._id).populate('list').populate('listItem');
How can I get all listItems, of all lists from a user with a x ID?
Assuming User, List, and ListItem are Collections, you should be able to accomplish this using $lookup..
Here is a live demo of the following query..
Query:
db.users.aggregate([
{
$match: {
uniqueId: 1
}
},
{
$lookup: {
from: "lists",
localField: "uniqueId",
foreignField: "userId",
as: "lists"
}
},
{
$lookup: {
from: "listItems",
localField: "uniqueId",
foreignField: "userId",
as: "listItems"
}
}
])
Dataset:
db={ // Simulates a DB ********
"users": [ // Simulates a Collection ********
{
"firstname": "John",
"lastname": "Smith",
"email": "jsmith#gmail.com",
"password": "password123",
"uniqueId": 1
},
{
"firstname": "Jane",
"lastname": "Doe",
"email": "doe#yahoo.com",
"password": "123password",
"uniqueId": 2
}
],
"lists": [ // Simulates a Collection ********
{
"userId": 1,
"name": "Johns List 1",
"items": [
11,
12,
13
]
},
{
"userId": 2,
"name": "Groceries",
"items": [
21,
22,
23
]
}
],
"listItems": [ // Simulates a Collection ********
{
"userId": 2,
"itemId": 21,
"title": "Apple",
"notes": []
},
{
"userId": 2,
"itemId": 22,
"title": "Banana",
"notes": []
},
{
"userId": 2,
"itemId": 23,
"title": "Strawberry",
"notes": []
},
{
"userId": 1,
"itemId": 11,
"title": "Oil Change",
"notes": []
},
{
"userId": 1,
"itemId": 12,
"title": "Pick Up Grandma",
"notes": []
},
{
"userId": 1,
"itemId": 13,
"title": "Go For Run",
"notes": []
}
]
}
Result:
[
{
"_id": ObjectId("5a934e000102030405000008"),
"email": "jsmith#gmail.com",
"firstname": "John",
"lastname": "Smith",
"listItems": [
{
"_id": ObjectId("5a934e000102030405000003"),
"itemId": 11,
"notes": [],
"title": "Oil Change",
"userId": 1
},
{
"_id": ObjectId("5a934e000102030405000004"),
"itemId": 12,
"notes": [],
"title": "Pick Up Grandma",
"userId": 1
},
{
"_id": ObjectId("5a934e000102030405000005"),
"itemId": 13,
"notes": [],
"title": "Go For Run",
"userId": 1
}
],
"lists": [
{
"_id": ObjectId("5a934e000102030405000006"),
"items": [
11,
12,
13
],
"name": "Johns List 1",
"userId": 1
}
],
"password": "password123",
"uniqueId": 1
}
]
NOTE: Updated to include NodeJS client details. See edits below.
I'm trying to avoid having to query ElasticSearch repeatedly to get the information I need.
Say I have a data set that consists of events in cities. Documents in the data set might look like this:
{
city: 'Berlin',
event: 'Dance party',
date: '2017-04-15'
},
{
city: 'Seattle',
event: 'Wine tasting',
date: '2017-04-18'
},
{
city: 'Berlin',
event: 'Dance party,
date: '2017-04-21'
},
{
city: 'Hong Kong',
event: 'Theater',
date: '2017-04-25'
}...
Now say the list of all tracked cities is known, and I need to get just the most recent event from each city. So I need to be able to feed into the query an array of city names, something along the lines of ['Berlin', 'Hong Kong', 'Seattle'] and get back only the bottom three events.
My current query can only accomplish this by running repeatedly with a size of 1, and doing an exact match on the city name, like so:
{
size: 1,
body: {
sort: [
{'date': {'order': 'desc'}}
],
query: {
'match_phrase': {'city': 'Berlin'}
}
}
}
Is there a way to write the script so I can pass the whole list of cities into one query and predictably get only the most recent entry for each city?
Edit
My new script looks like this:
{
'query': {
'match_all': {}
},
'_source': ['city', 'event', 'date'],
'aggs': {
'cities': {
'terms': {
'field': 'city',
'size': 100
},
'aggs': {
'top_cities': {
'top_hits': {
'size': 1,
'_source': 'event',
'sort': {
'date': 'desc'
}
}
}
}
}
}
}
This looks like it really should work. But I'm still missing tons of cities I know are in there, and one appears multiple times.
I'm running this in Node, with the elasticsearch-js package. The client executed this way:
let client = new elasticSearch.Client(
{
"host": [
"host1:9200",
"host2:9200",
"host3:9200"
]
}
);
client.search(SEARCH_PARAMS)
.then(function (resp) {
console.log(JSON.stringify(resp));
});
Here is a (sanitized) version of the resulting JSON:
{
"took": 77,
"timed_out": false,
"_shards": {
"total": 42,
"successful": 42,
"failed": 0
},
"hits": {
"total": 5685608,
"max_score": 1,
"hits": [{
"_index": "sanitized",
"_type": "sanitized",
"_id": "AVu489lVgqYk_9QxQb-U",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-15",
"city": "Berlin"
}
}, {
"_index": "sanitized",
"_type": "sanitized",
"_id": "AVu489lVgqYk_9QxQb-X",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-15",
"city": "Berlin"
}
}, {
"_index": "sanitized",
"_type": "sanitized_variant_1",
"_id": "AVu489lVgqYk_9QxQb-a",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-29",
"city": "Berlin"
}
}, {
"_index": "sanitized",
"_type": "sanitized_variant_2",
"_id": "AVu489lVgqYk_9QxQb-b",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-29",
"city": "Berlin"
}
}, {
"_index": "sanitized",
"_type": "sanitized_variant_2",
"_id": "AVu489lVgqYk_9QxQb-d",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-29",
"city": "Hong Kong"
}
}, {
"_index": "sanitized",
"_type": "sanitized_variant_2",
"_id": "AVu489lVgqYk_9QxQb-f",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-29",
"city": "Hong Kong"
}
}, {
"_index": "sanitized",
"_type": "sanitized_variant_2",
"_id": "AVu49AkKCe9swQD44WnN",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-29",
"city": "Seattle"
}
}, {
"_index": "sanitized",
"_type": "sanitized_variant_2",
"_id": "AVu49AkKCe9swQD44WnP",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-29",
"city": "New York"
}
}, {
"_index": "sanitized",
"_type": "sanitized_variant_1",
"_id": "AVu49AkKCe9swQD44WnY",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-29",
"city": "Berlin"
}
}, {
"_index": "sanitized",
"_type": "sanitized_variant_2",
"_id": "AVu49AkKCe9swQD44Wnb",
"_score": 1,
"_source": {
"event": "Dance party",
"date": "2017-04-29",
"city": "Berlin"
}
}]
}
}
On closer inspection, the aggregations are not being added to the resp object for some reason.
In addition to filtering the cities in the query, I suggest to use a terms aggregation on the city field and then a top_hits sub-aggregation to retrieve on the latest event per city:
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"cities": {
"terms": {
"field": "city",
"size": 100
},
"aggs": {
"top_events": {
"top_hits": {
"size": 1,
"_source": "event",
"sort": {
"date": "desc"
}
}
}
}
}
}
}
You can use a Terms Query, passing all those cities, something like:
"query": {
"terms": {
"city": [
"BERLIN",
"RIO DE JANEIRO"
]
}
},
"size": 3,
"_source": "city",
"sort": [
{
"date": {
"order": "desc"
}
}
]
}
What is the query to update below data with mongoose. So 3 fields are going to be updated. Top Parent Points, Categories Points and Tag Points.
{
"_id": "561fba5e7fac41a4055fad45",
"fullName": "Test",
"points": 45,
"level": 1,
"categories": [
{
"name": "Computer Science",
"points": 15,
"level": 1,
"_id": "561fba5e7fac41a4055fad46",
"tags": [
{
"name": "C#",
"points": 10,
"level": 1,
"_id": "561fba5e7fac41a4055fad47"
},
{
"name": "Java",
"points": 5,
"level": 1,
"_id": "561fba5e7fac41a4055ert12"
}
]
},
{
"name": "History",
"points": 30,
"level": 2,
"_id": "562407d4e3edf2113f61ac37",
"tags": [
{
"name": "WW2",
"points": 30,
"level": 2,
"_id": "56240797e3edf2113f61ac36"
}
]
}
]
}
to this one. When user gets a point from a specific tag, it will effect all parents. Let's say, user gets 10 points from C# then i have to update mongodb to this.
{
"_id": "561fba5e7fac41a4055fad45",
"fullName": "Test",
**"points": 55,**
"level": 1,
"categories": [
{
"name": "Computer Science",
**"points": 25,**
"level": 1,
"_id": "561fba5e7fac41a4055fad46",
"tags": [
{
"name": "c#",
**"points": 20,**
"level": 1,
"_id": "561fba5e7fac41a4055fad47"
},
{
"name": "Java",
"points": 5,
"level": 1,
"_id": "561fba5e7fac41a4055ert12"
}
]
},
{
"name": "History",
"points": 30,
"level": 2,
"_id": "562407d4e3edf2113f61ac37",
"tags": [
{
"name": "WW2",
"points": 30,
"level": 2,
"_id": "56240797e3edf2113f61ac36"
}
]
}
]
}
you should use $elemMatch for querying your object
db.tests.update({_id: yourTestId, categories: {$elemMatch: {_id: categoryId}}}, {$set: {$inc: {"categories.$.points": 10, points: 10}}})
So you querying only needed array element and update it values with $ reference
i need to find record matching userId. the userId can be in any level of document.
It can be in parent level or it can be inside friends array.
[{
"_id": "543357620c9af6066e689713",
"createdDate": "2014-10-06 08:00 pm",
"cancle": false,
"eventDate": "2014/12/12",
"eventstatus": true,
"location": "chennai",
"userId": "54334def7e85de48638d1069",
"createdBy": "four",
"eventName": "jamba",
"__v": 0,
"friends": []
},
{
"_id": "543356fe0c9af6066e68970c",
"createdDate": "2014-10-06 07:59 pm",
"cancle": false,
"eventDate": "2014/12/12",
"eventstatus": true,
"location": "chennai",
"userId": "54310801e2659ecc3650100b",
"createdBy": "one",
"eventName": "tea ",
"__v": 0,
"friends": [
{
"userId": "54310814e2659ecc3650100c",
"userName": "two",
"phoneNumber": "22222222"
},
{
"userId": "54310945e2659ecc3650100d",
"userName": "three",
"phoneNumber": "33333333"
},
{
"userId": "54334def7e85de48638d1069",
"userName": "four",
"phoneNumber": "44444444"
}
]
}]
i am trying for long time. Any help is highly appreciated.
You need the $or operator. Also, you don't need to iterate to query for elements within an array. Assuming your collection is named Events:
Events.find({
$or: [
{ _id: req.params.userId },
{ 'friends.userId': req.params.userId }
]
}).exec();