Updating array inside two object in mongod - javascript

I have a collection of the structure as follows:
collection name : "positions"
Structure
{
"_id" : "vtQ3tFXg8THF3TNBc",
"candidatesActions" : {
"sourced" : [ ],
},
"appFormObject" : {
"name" : "✶ mandatory",
"questions" : [
{
"qusId" : "qs-585494",
"type" : "simple",
"qus" : "Which was your previous company"
},
{
"qusId" : "qs-867766",
"type" : "yesNo",
"qus" : "Are you willing to relocate?",
"disqualify" : "true"
}
]
}
}
I want to update "qus" field of the above collection whose _id is "vtQ3tFXg8THF3TNBc" and "qusId" is "qs-585494".

Try following....
db.positions.update(
{_id: "vtQ3tFXg8THF3TNBc", "appFormObject.questions.qusId":"qs-585494"},
{$set:{"appFormObject.questions.$.qus": "this is updated value"}}
)

Use following query
db.positions.findAndModify({
query: { _id: "vtQ3tFXg8THF3TNBc", "appFormObject.questions.qusId":"qs-585494"} ,
update: { $set: { 'appFormObject.questions.$.qus': 'Brilliant Green' } },
});
Thanks

Related

How can I access(and convert) 'date' to Javascript?

Here is MongoDB scheme.
{
"_id" : ObjectId("222222"),
"active" : false,
"amount" : "15%",
"description" : "15% discount",
"name" : "20200628-test",
"policies" : {
"apply" : [
{
"name" : "expiryDate",
"params" : {
"date" : ISODate("2020-07-06T14:59:59.999Z")
}
},
{
"name" : "isApplyCategoryExist"
}
],
"discount" : [],
"conflict" : [
{
"name" : "exclusive"
}
],
"grant" : []
},
"target" : {
"sku" : "",
"products_ids" : [],
"category_ids" : [
ObjectId("11111111")
]
},
"title" : "15% coupon"
}
I want to access date.
For example, "policies.apply.params.date"...
I don't know how to access 'date' to Javascript.
Please let me know...
apply is an array, so you have to give it index which you want to get.
var num = 0; // pick up an array number you want
var date = policies.apply[num].params.date;
Your policies.apply is an array so if you want to access "2020-07-06T14:59:59.999Z", you should do this:
policies.apply[0].params.date
But the "policies.apply[1]" doesn't have params (params.date also) so you can write a function to get date like this:
function get_apply_date(index) {
if(policies.apply[index].params && policies.apply[index].params.date)
return policies.apply[index].params.date;
return undefined; // or null
}

How to filter out text fields in a complex query?

I've got a lot of doc filters on my UI (date ranges, checkboxes, input fields), so the query is generated dynamically - that's why I decided to create a boolean query, and push everything to must array. This is the example of my request:
const {
body: {
hits
}
} = await esclient.search({
from: filterQuery.page || 0,
size: filterQuery.limit || 1000,
index,
body: query
});
Checkboxes (I used additional bool.should inside must array) and date range work perfectly, but term/match filtering is not working at all:
{
"query": {
"bool": {
"must": [
{"match": { "issueNumber": "TEST-10" }}
]
}
}
}
The query above gives me all the documents from the index that contains "TEST" (with their scores), if I change match to term - it returns an empty array.
As my field is of a type 'text', I've also tried filter query - ES still gives all the documents with 'TEST' word:
{
"query": {
"bool": {
"must": [
{
"bool": {
"filter": {
"match": {"issueNumber": "TEST-10"}
}
}
}
]
}
}
}
This is how my hit looks like:
{
"_index" : "test_elastic",
"_type" : "_doc",
"_id" : "bj213hj2gghg213",
"_score" : 0.0,
"_source" : {
"date" : "2019-11-26T13:27:01.586Z",
"country" : "US",
"issueNumber" : "TEST-10",
}
Can someone give me input on how to filter the docs properly in complex query?
This is the structure of my index:
{
"test_elasticsearch" : {
"aliases" : { },
"mappings" : {
"properties" : {
"country" : {
"type" : "text"
},
"date" : {
"type" : "date"
},
"issueNumber" : {
"type" : "text"
}
}
},
"settings" : {
"index" : {
"creation_date" : "1574759226800",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "PTDsdadasd-ERERER",
"version" : {
"created" : "7040299"
},
"provided_name" : "logs"
}
}
}
}
Ok, the problem is that your issueNumber field has not the right type, it should be keyword instead of text if your goal is to make exact searches on it. Same for country. Modify your mapping like this:
"properties" : {
"country" : {
"type" : "keyword"
},
"date" : {
"type" : "date"
},
"issueNumber" : {
"type" : "keyword"
}
}
Then reindex your data and your queries will work.

mongoDB: Can't add an field to an array object

This is how my db document looks like:
{
"_id" : "aN2jGuR2rSzDx87LB",
"content" : {
"en" : [
{
"content" : "Item 1",
"timestamp" : 1518811796
}
]
}
}
Now I need to add another field in the first object of the content.en array.
The document itself gets selected by an ID.
The result should be:
{
"_id" : "aN2jGuR2rSzDx87LB",
"content" : {
"en" : [
{
"content" : "Item 1",
"timestamp" : 1518811796,
"user" : {
"id" : 'userId'
}
}
]
}
}
I tried to do it like this, but nothing is happening. I don't even get an error message.
Content.update(
{ _id: id },
{
$addToSet: {
'content.en.0.user': {
id: 'userId',
}
}
}
)
Also I would like to use an variable for the language. How do I do that? Something like 'content.' + language + '.0.user'...
$addToSet is useful when you want to add someting to an array. In your case you want to modify first element of your array (at index 0) so you should simply use $set (which is field update operator):
Content.update(
{ _id: "aN2jGuR2rSzDx87LB" },
{
$set: {
"content.en.0.user": {
id: "userId",
}
}
}
)

MongoDB: Getting document and only one object of an array

I got multiple documents like this:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM",
"timestamp" : 1453731403807,
"message" : "some text",
"name" : "Tom"
},
{
"id" : "BAHx9KeKjuMePce6f",
"timestamp" : 1453731403808,
"message" : "some text",
"name" : "Bob"
},
{
"id" : "ePce6fBAHx9KeKjuM",
"timestamp" : 1453731403809,
"message" : "some text",
"name" : "Tom"
}
]
}
I get this document by using this find-query:
Collection.find({}, { sort: { title: 1 }});
But I don't need the complete notes field. I'm only interested in the id of the last note-object. That means I have to order all notes object by timestamp and just take the first (=newest) one.
I'm not quite sure, if I can do that by the find-query or if I have to do that after getting the complete data.
So the best result for me would be:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM"
}
]
}
You can use the $slice projection to limit the number of array elements returned. For example:
db.collection.find({}, {title: 1, "notes.id": 1, notes: {$slice: 1}}).sort({title: 1});
Will return:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM"
}
]
}

MongoDB Aggregate - Unwind, group and project

Using the collection Users, is it possible to retrieve the below unique list of organisations/owners? If this current set up isn't possible, is it possible to get the same results from two ID-linked collections with one query?
Currently, using Mongoose I can only retrieve the group of organisation names:
Current query
userModel.aggregate([
{ $unwind:'$organisations' }
, { $group: { name: '$organisations.name' } }
])
Users
{ "_id" : ObjectId("53f4a94e7c88310000000001"),
"email" : "bob#example.com",
"organisations" : [
{
"name" : "OrgOne",
"isOwner" : true
}
]
},
{ "_id" : ObjectId("53f4a94e7c88310000000002"),
"email" : "ash#something.com",
"organisations" : [
{
"name" : "OrgOne"
}
]
},
{ "_id" : ObjectId("53f4a94e7c88310000000003"),
"email" : "george#hello.com",
"organisations" : [
{
"name" : "OrgTwo",
"isOwner" : true
}
]
}
Results
{ "orgName" : "OrgOne",
"owner" : 53f4a94e7c88310000000001
},
{ "orgName" : "OrgTwo",
"owner" : 53f4a94e7c88310000000003
}
Thanks in advance, Nick
Seems like an odd use of aggregation to me, but possibly there are several "organisations" per user here, so I guess I'll continue:
userModel.aggregate(
[
{ "$match": { "organisations.isOwner": true } },
{ "$unwind": "$organisations" },
{ "$match": { "organisations.isOwner": true } },
{ "$group": {
"_id": "$organisations.name",
"owner": { "$first": "$_id" }
}}
],
function(err,result) {
}
);
If there is more than one owner and you need some precedence then you can implement a $sort before the group. Or otherwise just $project rather than group in order to get everyone.

Categories

Resources