Related
Problem:
I need to only update one document in the spots available array that has an id of "empty". My previous query was updating all matching sub documents with "empty" as the id; which is no good Example Below. So I decided to use aggregation so that I could add a limit stage so that I could only update one item, but come to find out I cannot update the original document with an aggregation. This leaves the only option to use an array filter that only updates one/first of its matches. Is this possible? I feel like there has to be a way to only update one match on an array filter and if there isn't this is definitely something that should be added.
My code:
This code updates every object with "empty"
const client = await clientPromise;
const db = client.db();
// const query = db.collection('events').aggregate(agg);
const query = await db.collection('events').updateOne({
_id: new ObjectId("6398c34ca67dbe3286452f23"),
createdBy: new ObjectId("636c1778f1d09191074f9690"),
"weights.weight": 12
},
{
$set: {
"weights.$.spotsAvailable.$[el2]": {
"name": "Wayne Wrestler",
"userId": new ObjectId("636c1778f1d09191074f9690")
}
}
},
{
arrayFilters: [{ "el2": { "userId": "empty" } }]
})
Example documents:
Event:
{
"_id": {
"$oid": "6398c34ca67dbe3286452f23"
},
"name": "test",
"createdBy": {
"$oid": "636c1778f1d09191074f9690"
},
"description": "testing",
"date": {
"$date": {
"$numberLong": "1645488000000"
}
},
"location": {
"type": "Point",
"coordinates": [
0,
0
]
},
"weights": [
{
"spotsAvailable": [
{
"name": "empty",
"userId": "empty"
},
{
"name": "empty",
"userId": "empty"
},
{
"name": "empty",
"userId": "empty"
}
],
"weight": 12
},
{
"spotsAvailable": [
{
// only one of these should've been updated, but both were
"name": "Wayne Wrestler",
"userId": {
"$oid": "636c1778f1d09191074f9690"
}
},
{
"name": "Wayne Wrestler",
"userId": {
"$oid": "636c1778f1d09191074f9690"
}
}
],
"weight": 15
}
],
"eventApplicants": [
{
"userId": {
"$oid": "636c1778f1d09191074f9690"
},
"name": "Wayne Wrestler",
"weight": 12
}
]
}
User:
{
"_id": {
"$oid": "636c1778f1d09191074f9690"
},
"name": "Wayne Wrestler",
"email": "wakywayne80#gmail.com",
"image": "https://lh3.googleusercontent.com/a/ALm5wu32gXjDIRxncjjQA9I4Yl-sjFH5EWsTlmvdM_0kiw=s96-c",
"emailVerified": {
"$date": {
"$numberLong": "1670864727212"
}
},
"createdEvents": [
{
"createdEventName": "test",
"createdEventDate": {
"$date": {
"$numberLong": "1645488000000"
}
},
"createdEventDescription": "testing",
"createdEventWeights": [
{
"weight": "12",
"filled": [
false,
false,
false
]
},
{
"weight": "15",
"filled": [
false,
false
]
}
],
"createdEventId": {
"$oid": "6398c34ca67dbe3286452f23"
}
}
],
"userSignedUpEvents": [],
"availableWeights": [
1,
123
],
"signedUpEvents": [
{
"eventId": {
"$oid": "636c722f67642c30dc5ffc30"
},
"eventName": "Utah",
"eventDate": {
"$date": {
"$numberLong": "1667913330000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "636c722f67642c30dc5ffc30"
},
"eventName": "Utah",
"eventDate": {
"$date": {
"$numberLong": "1667913330000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "637ec484ac2d675b30590b47"
},
"eventName": "Maybe?",
"eventDate": {
"$date": {
"$numberLong": "1672272000000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "636c722f67642c30dc5ffc30"
},
"eventName": "Utah",
"eventDate": {
"$date": {
"$numberLong": "1667913330000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "638d5274628db2a7bf61df49"
},
"eventName": "Eva's",
"eventDate": {
"$date": {
"$numberLong": "1698019200000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "636c722f67642c30dc5ffc30"
},
"eventName": "Utah",
"eventDate": {
"$date": {
"$numberLong": "1667913330000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "6398a922abb5c168ede595fb"
},
"eventName": "Nikko's event",
"eventDate": {
"$date": {
"$numberLong": "1670976000000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "6398a922abb5c168ede595fb"
},
"eventName": "Nikko's event",
"eventDate": {
"$date": {
"$numberLong": "1670976000000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "6398c34ca67dbe3286452f23"
},
"eventName": "test",
"eventDate": {
"$date": {
"$numberLong": "1645488000000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "6398c34ca67dbe3286452f23"
},
"eventName": "test",
"eventDate": {
"$date": {
"$numberLong": "1645488000000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "6398c34ca67dbe3286452f23"
},
"eventName": "test",
"eventDate": {
"$date": {
"$numberLong": "1645488000000"
}
},
"accepted": false
},
{
"eventId": {
"$oid": "6398c34ca67dbe3286452f23"
},
"eventName": "test",
"eventDate": {
"$date": {
"$numberLong": "1645488000000"
}
},
"accepted": false
}
]
}
I have tried:
Pluging in variables without the new ObjectId syntax
Plugin in variables with the new ObjectId syntax
Using the exact same hardcoded values that I got from copying the aggregation code from compass for the node driver
All of these either don't work or result in every subdocument with "empty" getting filled
One option is to use update with pipeline:
Since this is a double nested array, it is easier to do it in two steps - internal and external
First create the "external" item to replace in weights array and call it newItem. It is calculated using $reduce which allow us to manipulate the internal array while looping on it.
Replace the relevant item on weights array with our newItem using $map with $cond
db.collection.update(
{_id: ObjectId("6398c34ca67dbe3286452f23"), "weights.weight": 12},
[
{$set: {
newItem: {$reduce: {
input: {$getField: {
input: {$first: {
$filter: {
input: "$weights",
as: "item",
cond: {$eq: ["$$item.weight", 12]}
}
}},
field: "spotsAvailable"
}},
initialValue: [],
in: {$concatArrays: [
"$$value",
{$cond: [
{$and: [
{$eq: ["$$this.userId", "empty"]},
{$not: {$in: [ObjectId("636c1778f1d09191074f9690"), "$$value.userId"]}}
]},
[{
name: "Wayne Wrestler",
userId: ObjectId("636c1778f1d09191074f9690")
}],
["$$this"]
]}
]}
}}
}},
{$set: {
weights: {$map: {
input: "$weights",
in: {$cond: [
{$eq: ["$$this.weight", 12]},
{$mergeObjects: [
"$$this",
{spotsAvailable: "$newItem"}
]},
"$$this"
]}
}},
newItem: "$$REMOVE"
}}
])
See how it works on the playground example
You can first $unwind the weights for easier processing first. Use $reduce to iterate through the weights.spotsAvailable array and use a compound object to store the result and a flag to indicate whether it is updated or not. Finally use the result to $merge back to the original document.
db.collection.aggregate([
{
$match: {
"_id": ObjectId("6398c34ca67dbe3286452f23"),
createdBy: ObjectId("636c1778f1d09191074f9690"),
"weights.weight": 12,
"weights.spotsAvailable.userId": "empty"
}
},
{
"$unwind": "$weights"
},
{
"$addFields": {
"results": {
"$reduce": {
"input": "$weights.spotsAvailable",
"initialValue": {
result: [],
updated: false
},
"in": {
"$cond": {
"if": {
$and: [
{
$eq: [
false,
"$$value.updated"
]
},
{
$eq: [
"empty",
"$$this.userId"
]
}
]
},
"then": {
result: {
"$concatArrays": [
"$$value.result",
[
{
"name": "Wayne Wrestler",
"userId": ObjectId("636c1778f1d09191074f9690")
}
]
]
},
updated: true
},
"else": {
result: {
"$concatArrays": [
"$$value.result",
[
"$$this"
]
]
},
updated: "$$value.updated"
}
}
}
}
}
}
},
{
$set: {
"weights.spotsAvailable": "$results.result",
"results": "$$REMOVE"
}
},
{
$group: {
_id: "$_id",
"name": {
$first: "$name"
},
"createdBy": {
$first: "$createdBy"
},
"description": {
$first: "$description"
},
"date": {
$first: "$date"
},
"location": {
$first: "$location"
},
"weights": {
$push: "$weights"
},
"eventApplicants": {
$first: "$eventApplicants"
}
}
},
{
"$merge": {
"into": "collection",
"on": "_id"
}
}
])
Mongo Playground
I'm new to mongoose, I'm confuse while create the query. Can you help me?
I have a movie document like this :
"movies": [
{
"id": "635611395a71beb6c5bf0b4d",
"title": "Mission: Impossible - Fallout",
"createdAt": "2022-10-24T04:14:54.445Z",
"cast": [
{
"actor": "635350c581d5b60383f0c4be",
"roleAs": "Ethan Hunt",
"leadActor": true,
"_id": "635658c18b9e50facd7f1fd1"
},
{
"actor": "63560bf55a71beb6c5bf0b1f",
"roleAs": "Ilsa Faust",
"leadActor": false,
"_id": "635658c18b9e50facd7f1fd2"
}
],
"poster": {
"url": "https://res.cloudinary.com/debfn35m1/image/upload/v1666603204/vczxb7lgbonjn8ydsyep.jpg",
"public_id": "vczxb7lgbonjn8ydsyep",
"responsive": [
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_640/v1666603204/vczxb7lgbonjn8ydsyep.jpg",
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_50/v1666603204/vczxb7lgbonjn8ydsyep.jpg"
]
},
"reviews": {
"ratingAvg": "5.0",
"reviewCount": 2
}
},
{
"id": "635614855a71beb6c5bf0bdc",
"title": "Spider-Man: No Way Home",
"createdAt": "2022-10-24T04:28:58.286Z",
"cast": [
{
"actor": "635350a881d5b60383f0c4b8",
"roleAs": "Peter Parker",
"leadActor": true,
"_id": "636a2d6520cf4cf14a11ef95"
},
{
"actor": "635611eb5a71beb6c5bf0b99",
"roleAs": "MJ",
"leadActor": false,
"_id": "636a2d6520cf4cf14a11ef96"
}
],
"poster": {
"url": "https://res.cloudinary.com/debfn35m1/image/upload/v1667902823/tajzr9hpulvzqoytgpxu.jpg",
"public_id": "tajzr9hpulvzqoytgpxu",
"responsive": [
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_640/v1667902823/tajzr9hpulvzqoytgpxu.jpg",
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_470/v1667902823/tajzr9hpulvzqoytgpxu.jpg",
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_50/v1667902823/tajzr9hpulvzqoytgpxu.jpg"
]
},
"reviews": {
"ratingAvg": "8.0",
"reviewCount": 2
}
},
This is my desired result:
{
"id": "635611395a71beb6c5bf0b4d",
"title": "Mission: Impossible - Fallout",
"createdAt": "2022-10-24T04:14:54.445Z",
"cast": [
{
"actor": "635350c581d5b60383f0c4be",
"roleAs": "Ethan Hunt",
"leadActor": true,
"_id": "635658c18b9e50facd7f1fd1"
},
{
"actor": "63560bf55a71beb6c5bf0b1f",
"roleAs": "Ilsa Faust",
"leadActor": false,
"_id": "635658c18b9e50facd7f1fd2"
}
],
"poster": {
"url": "https://res.cloudinary.com/debfn35m1/image/upload/v1666603204/vczxb7lgbonjn8ydsyep.jpg",
"public_id": "vczxb7lgbonjn8ydsyep",
"responsive": [
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_640/v1666603204/vczxb7lgbonjn8ydsyep.jpg",
"https://res.cloudinary.com/debfn35m1/image/upload/c_scale,w_50/v1666603204/vczxb7lgbonjn8ydsyep.jpg"
]
},
"reviews": {
"ratingAvg": "5.0",
"reviewCount": 2
}
},
Im trying to write a filter function to get all movie that has Tom Cruise with actorId as a parameter but cannot get the result.
Can someone please help me with this ?
Since your actor id is inside a cast array with key actor you must specify your key while match, check the updated code below
exports.actorAggregation = (actorId) => {
return [
{
$lookup: {
from: "Movie",
localField: "cast",
foreignField: "_id",
as: "actorFilter",
},
},
{ $unwind: "$cast" },
{
$match: {
"cast.actor._id": { $in: [actorId] }, // or "cast.actor": { $in: [actorId] },
status: { $eq: "public" },
},
},
{
$project: {
title: 1,
poster: "$poster.url",
responsivePosters: "$poster.responsive",
createdAt: "$createdAt",
},
},
];
};
I'm trying to filter a nested object and sort by the result, however, I tried some things without success, I'll leave my initial attempt and it works partially, it just filters according to what I have in my search variable, but all the results come of this nested object as it is inside the 'root' which is another nested object
Elastic version: 7.13.0 with NodeJS
using #elastic/elasticsearch official package from npm
let params: RequestParams.Search = {
index: index,
body: {
size: 30,
query: {
bool: {
must: [
{
nested: {
path: "profile",
query: {
bool: {
must: [
{
match: {
"profile.id": profileId,
},
},
],
},
},
},
},
],
filter: [
{
nested: {
path: "profile.following",
ignore_unmapped: true,
query: {
query_string: {
fields: [
"profile.following.name",
"profile.following.username",
],
query: searchWord + "*",
},
},
},
},
],
},
},
},
};
I need it to be this specific 'profile.id' that is passed by parameter in the function, so the result is only 1 profile with N people that it follows
the document is mapped as follows, I left only the fields relevant to the question:
{
"mappings": {
"_doc": {
"properties": {
"id": {
"type": "integer"
},
"phone": {
"type": "text"
},
"profile": {
"type": "nested",
"properties": {
"id": {
"type": "integer"
},
"username": {
"type": "text"
},
"following": {
"type": "nested",
"properties": {
"id": {
"type": "integer"
},
"isAwaitingApproval": {
"type": "boolean"
},
"name": {
"type": "text"
},
"profilePicURL": {
"type": "text"
},
"username": {
"type": "text"
}
}
}
}
}
}
}
}
}
an example of a current result is:
with the following parameters (profileId:141, searchWord: "para" )
{
"res": [
{
"profilePicURL": "localimage",
"name": "donor donor",
"id": 140,
"username": "victorTesteElastic2",
"isAwaitingApproval": false
},
{
"profilePicURL": "localimage",
"name": "para ser seguido",
"id": 142,
"username": "victorprivate",
"isAwaitingApproval": true
}
]
}
the desired result is:
{
"res": [
{
"profilePicURL": "localimage",
"name": "para ser seguido",
"id": 142,
"username": "victorprivate",
"isAwaitingApproval": true
}
]
}
with some more research I got what I needed, I'll leave the answer here in case anyone needs it too
let params: RequestParams.Search = {
index: index,
body: {
size: 30,
query: {
bool: {
must: [
{
nested: {
path: "profile",
query: {
bool: {
must: [
{
match: {
"profile.id": profileId,
},
},
],
},
},
},
},
{
nested: {
path: "profile",
inner_hits: {
name: "profile",
},
query: {
nested: {
path: "profile.following",
inner_hits: {
name: "following",
},
ignore_unmapped: true,
query: {
query_string: {
fields: [
"profile.following.name",
"profile.following.username",
],
query: searchWord + "*",
},
},
},
},
},
},
],
},
},
},
};
I basically put in must what was in the filter, mapped the nested object from above, in this case the profile, and put the tag inner_hits for profile and inner_hits for followings, that's the only way it worked
the answer I need was returned here:
body.hits.hits[0].inner_hits.profile.hits.hits[0].inner_hits.following.hits.hits
below is an example of the answer:
{
"res": [
{
"_index": "donor",
"_type": "_doc",
"_id": "P3VWNnsB4coAEhD-F3fF",
"_nested": {
"field": "profile",
"offset": 0,
"_nested": {
"field": "following",
"offset": 0
}
},
"_score": 1,
"_source": {
"profilePicURL": "localimage",
"name": "donor donor",
"id": 140,
"username": "victorTesteElastic2",
"isAwaitingApproval": false
}
},
{
"_index": "donor",
"_type": "_doc",
"_id": "P3VWNnsB4coAEhD-F3fF",
"_nested": {
"field": "profile",
"offset": 0,
"_nested": {
"field": "following",
"offset": 1
}
},
"_score": 1,
"_source": {
"profilePicURL": "localimage",
"name": "para ser seguido",
"id": 142,
"username": "victorprivate",
"isAwaitingApproval": true
}
}
]
}
the filtered data I really need that have been matched in must is in this array, where I need to iterate and look at _source which is the data that is indexed
Can anyone suggest me how can I get only those records from my collection? which is having multiple matched Values in my embedded document. here is my collection having name users.
{
"_id": "5b86fd75d595a923452366d7",
"name": "Mike I",
"email": "ppp#ppp.com",
"status": true,
"role": "seller",
"parking_space": [
{
"_id": "5b8cc33846e5360e741cae77",
"parking_name": "New Parking",
"street_address": "700 broadway",
"opening_days_and_timings": [
{
"day": "Monday",
"opening_time": "09:00",
"closing_time": "10:00",
"_id": "5b9119c93f7bc41306745a57"
},
{
"day": "Sunday",
"opening_time": "22:30",
"closing_time": "23:30",
"_id": "5b9119c93f7bc41306745a58"
},
{
"day": "Tuesday",
"opening_time": "11:00",
"closing_time": "23:59",
"_id": "5b9119c93f7bc41306745a59"
}],
"location":
{
"type": "Point",
"coordinates": [-117.15833099999998, 32.7157529]
},
"status": true,
},
{
"_id": "5b8e1df246e5360e741cae8a",
"parking_name": "Gupta's parking",
"street_address": "IT Park Rd, Phase - I",
"opening_days_and_timings": [
{
"day": "Wednesday",
"opening_time": "00:00",
"closing_time": "23:59",
"_id": "5b9119df3f7bc41306745a60"
},
{
"day": "Thursday",
"opening_time": "00:00",
"closing_time": "23:59",
"_id": "5b9119df3f7bc41306745a61"
}],
"location":
{
"type": "Point",
"coordinates": [76.84613349999995, 30.7259198]
},
"status": true,
}}
What I am trying to do here is to get only those parking data which is having days like "Wednesday" and "Thursday" only i just want that parking data. like this.
{
"_id": "5b86fd75d595a923452366d7",
"name": "Mike I",
"email": "ppp#ppp.com",
"status": true,
"role": "seller",
"parking_space": [
{
"_id": "5b8e1df246e5360e741cae8a",
"parking_name": "Gupta's parking",
"street_address": "IT Park Rd, Phase - I",
"opening_days_and_timings": [
{
"day": "Wednesday",
"opening_time": "00:00",
"closing_time": "23:59",
"_id": "5b9119df3f7bc41306745a60"
},
{
"day": "Thursday",
"opening_time": "00:00",
"closing_time": "23:59",
"_id": "5b9119df3f7bc41306745a61"
}],
"location":
{
"type": "Point",
"coordinates": [76.84613349999995, 30.7259198]
},
"status": true,
}}
and to get result like this i am using query as follow but it is not returning me the as i want. below is the query i am using.
User.aggregate([{
"$match": {
"parking_space.location": {
"$geoWithin": {
"$centerSphere": [
[parseFloat(req.body.long), parseFloat(req.body.lat)], 7 / 3963.2
]
}
},
$and : [ { "parking_space.opening_days_and_timings.day" : 'Thursday' }, { "parking_space.opening_days_and_timings.day" : 'Wednesday' }
"parking_space.opening_days_and_timings.day": getDayOfWeek(req.body.date)
}
}, {
"$unwind": "$parking_space"
}, {
"$match": {
"parking_space.location": {
"$geoWithin": {
"$centerSphere": [
[parseFloat(req.body.long), parseFloat(req.body.lat)], 7 / 3963.2
]
}
},
}
}], function(err, park_places) {
if (err) {
return res.send({
data: err,
status: false
});
} else {
return res.send({
data: park_places,
status: true,
msg: "Parking data according to location"
});
}
});
This is the query i am using which is not returning the above desired result can someone suggest me something to get the result
You can use below aggregation.
User.aggregate([
{
"$match": {
"parking_space.location": {
"$geoWithin": {
"$centerSphere": [
[parseFloat(req.body.long), parseFloat(req.body.lat)], 7 / 3963.2
]
}
},
{"parking_space.opening_days_and_timings.day" :{"$in":['Thursday', 'Wednesday', getDayOfWeek(req.body.date)]}}
}
},{
"$addFields": {
"parking_space": {
"$filter": {
"input": "$parking_space",
"cond": {"$setIsSubset":[['Thursday', 'Wednesday', getDayOfWeek(req.body.date)], "$$this.opening_days_and_timings.day"]}
}
}
}
}
],
function(err, park_places) {
if (err) {
return res.send({
data: err,
status: false
});
} else {
return res.send({
data: park_places,
status: true,
msg: "Parking data according to location"
});
}
});
I am using elasticsearch in a node environment.
This is my data model :
"_source": {
"repo_id": "ecom-test",
"pr_id": "1",
"pr_status": "approved",
"date_created": "2016-12-14T12:55:50.317Z",
"date_modified": "2016-12-14T12:55:50.317Z",
"comments": [
{
"tuple": {
"reviewee": "Max",
"reviewer": "Vic"
},
"nb": "1",
"type": "typo"
},
{
"tuple": {
"reviewee": "Antoine",
"reviewer": "Vic"
},
"nb": "2",
"type": "logic"
}
]
}
I add comments using the following code :
client.update({
index: 'loreal',
type: 'reviews',
id: reviewID,
body: {
script: {
inline: "ctx._source.comments.add(params.comment)",
lang: "painless",
params: {
comment: {
tuple: {
reviewee: data.reviewee,
reviewer: data.reviewer
},
nb: data.nb,
type: data.type
}
}
}
}
})
But when a comment with the same "reviewee", "reviewer" AND "logic" already exists i would like to update the "nb" attribute instead of creating a new item in the "comments" array.
I thought i would first make a search but I can't find a way to make a search that matches any element of the array "comments" that has those three values.
I really hope you guys can give me a hand with this, it's been a long time I am searching =s.
Thanks in advance
Given the struct of your document, I would have defined the comment field like a nested object: see the documentation example which is pretty close to your use case: https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-objects.html#nested-objects
Considering that you got in param the reviewee value, I would use the combination of nested query and bool query. https://www.elastic.co/guide/en/elasticsearch/guide/2.x/nested-query.html
{
"query": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [{
"match": {
"comments.tuple.reviewee": "your reviewee"
}
}, {
"match": {
"comments.tuple.reviewer": "your reviewee"
}
}, {
"term": {
"comments.type": "logic"
}
}]
}
}
}
}
Here the test I wrote:
PUT test
{
"mappings": {
"item": {
"properties": {
"comments": {
"type": "nested"
}
}
}
}
}
POST test/item
{ "comments": [
{
"tuple": {
"reviewee": "Max",
"reviewer": "Max"
},
"nb": "1",
"type": "logic"
},
{
"tuple": {
"reviewee": "Antoine",
"reviewer": "Vic"
},
"nb": "2",
"type": "logic"
}
]
}
POST test/item
{
"comments": [
{
"tuple": {
"reviewee": "Max",
"reviewer": "Max"
},
"nb": "1",
"type": "test"
},
{
"tuple": {
"reviewee": "Antoine",
"reviewer": "Vic"
},
"nb": "2",
"type": "logic"
}
]
}
POST test/item
{
"comments": [
{
"tuple": {
"reviewee": "Max",
"reviewer": "Mac"
},
"nb": "1",
"type": "logic"
},
{
"tuple": {
"reviewee": "Antoine",
"reviewer": "Vic"
},
"nb": "2",
"type": "logic"
}
]
}
GET /test/item/_search
{
"query": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [{
"match": {
"comments.tuple.reviewee": "Max"
}
}, {
"match": {
"comments.tuple.reviewer": "Max"
}
}, {
"term": {
"comments.type": "logic"
}
}]
}
}
}
}}