MongoDB - How can I check if some element in an array meets a condition with another element of an array? - arrays

I have the following objects in my Java APP:
[
{
"from" : "11/12/2020",
"to" : "12/12/2019"
},
{
"from" : "13/12/2020",
"to" : "14/12/2020
}
]
and in my DB I have the following objects:
[
{
"from" : "01/12/2020",
"to" : "14/12/2019"
},
{
"from" : "20/12/2020",
"to" : "30/12/2020
}
]
What query can I write to check if any of the dates from or to from any object in my first Java APP will be gte or lte than any of the from or to values from my DB objects?
Thanks!

You will have to iterate over all DB entries and compare them to your object.
If you are using JPA Repositories to communicate with your DB, you can do that like this:
List<Entry> matches = dataRepository.findAll().stream().filter(dbEntry -> dbEntry.equals(myEntry)).collect(Collectors.asList());
The ArrayList will now contain all of your matches from the Database.

Related

How to use react-table to put object (json dict) key/value pairs on rows and not put keys on columns

I am pretty new to react, but am trying to do the following ...
Am making API requests to ElasticSearch (using elasticsearch npm package) from reactjs.
I want to put some of the returned json data (after putting in Objects and distilling keys/values) into a table using the react-table package ...
AFAI understand most examples on the react-table documentation talk about mapping object keys to columns and then using the column accessors to populate the values (from key/values) in the correct columns as rows. So, map objects keys to columns and put values in as rows ...
But in my case I want to put values AND keys into rows and have a few manually defined columns ...
At this point there is no proper mapping between columnn accessors and object keys ...
Is ther ea way to do this using react-table? WOuld appreciate if someone can point me in the right direction reagrding documentation/examples ...
Also, my returend JSON data has some nested dicts ...
See example dataset below
"hits" : [
{
"_index" : "obj-model",
...
"_source" : {
"MoClass" : {
"Name" : "fvBD",
"Description" : "A bridge domain is a unique l2 forwarding domain that contains one or more subnets. Each bridge domain must be linked to a context.",
"Class ID" : "1887",
"Class Label" : "Bridge Domain",
"AbstractionLayer" : "Logical Model",
"Write Access" : "[admin, tenant-connectivity-l2]",
"Read Access" : "[access-connectivity-l3, admin, fabric-connectivity-l3, nw-svc-device, nw-svc-policy, tenant-connectivity-l2, tenant-connectivity-l3, tenant-connectivity-mgmt, tenant-epg, tenant-ext-connectivity-l2, tenant-ext-connectivity-l3, tenant-ext-protocol-l3, tenant-network-profile, tenant-protocol-l2, tenant-protocol-l3, tenant-security]",
"Semantic Scope" : "EPG",
"Semantic Scope Evaluation Rule" : "Explicit",
"Monitoring Policy Source" : "Explicit",
"Property" : [ <===================== NESTED DICT
{
"Name" : "OptimizeWanBandwidth",
"Comment" : "OptimizeWanBandwidth flag is enabled between sites",
"Constants" : [
"no",
"yes"
]
},
{
"Name" : "annotation",
"Comment" : "NO COMMENTS",
"Constants" : [
"no",
"yes"
]
},
...

TextCriteria with diacriticSensitive. Spring Data MongoDB 1.10.9

I'm trying to create a search in my MongoDB database to search the "name" field without taking into account the accents
I need to create an index in the field:
// create index
#Indexed
#Field("nombre")
private String nombre;
Check in the BBDD that it is created correctly:
db.empleado_bk.getIndexes();
{
"v" : 2,
"key" : {
"nombre" : 1
},
"name" : "nombre",
"ns" : "elser2.empleado_bk"
}
I modify my repository to search in text without taking accents into account
if (StringUtils.isNoneBlank(dtoFilter.getNombre())) {
query.addCriteria(TextCriteria.forDefaultLanguage().diacriticSensitive(true).matching("nombre"));
}
But when looking for that field, I get the following error:
org.springframework.data.mongodb.UncategorizedMongoDbException: Query failed with error code 27 and error message 'text index required for $text query'
Can someone tell me if I'm doing something wrong if I need to do something else
You applied a standard index with #Indexed. To apply a text search index, you need to use #TextIndexed.

MongoDB Convert String to Array

I'm very new to MongoDB and experience some difficulties in importing data into the database. Now I have a collection of documents which looks like
db.Question.findOne()
{
"_id" : ObjectId("124"),
"Answers" : "[\"502\",\"784\",\"1060\"]",
}
The Answers are now stored as a single string. However I want to convert it to a list like below so I could unwind it when doing query.
{
"_id" : ObjectId("124"),
"Answers" : ["502","784","1060"],
}
Any idea how to do it ? Thanks.
You can use JSON.parse() to change string type to list and then save the collection with update element. Below is a example:
db.Question.find({}).snapshot().forEach(function (el){el.Answers=JSON.parse(el.Answers);db.Question.save(el)});
You simply need to apply JSON.parse to each of these strings:
> JSON.parse("[\"502\",\"784\",\"1060\"]")
[ '502', '784', '1060' ]
First remove "[" and "]" in the data, then use below code, which create a new attribute,answers, which is a array/list that holds individual numbers:
db.Question.find({}).snapshot().forEach(function (el) {
el.answers=el.Answers.substring(1,el.Answers.length-1);
el.answers = el.Answers.split(',');
db.Question.save(el);
});

MongoDb - Find a specific obj within nested arrays

I hope someone can shed some light on this issue that I have, it's driving me crazy to a point that I have been spending the past three days, learning more and more about mongoDB but still can't figure out this simple query.
What I need to do is to get the object containing the "carId" = "3C".
In other words the object that I want the query to return is:
{
"carId" : "3C",
"_id" : ObjectId("51273329b64f07a40ef1c15e")
}
Here is the dataset (cars):
{
"_id" : ObjectId("56223329b64f07a40ef1c15c"),
"username" : "john",
"email" : "john#john.com",
"accounts" : [
{
"_id" : ObjectId("56322329b61f07a40ef1c15d"),
"cars" : [
{
"carId" : "6A",
"_id" : ObjectId("56323329b64f07a40ef1c15e")
},
{
"carId" : "6B",
"_id" : ObjectId("56323329b64f07a40ef1c15e")
}
]
}
]
},
{
"_id" : ObjectId("56223125b64f07a40ef1c15c"),
"username" : "paul",
"email" : "paul#paul.com",
"accounts" : [
{
"_id" : ObjectId("5154729b61f07a40ef1c15d"),
"cars" : [
{
"carId" : "5B",
"_id" : ObjectId("56323329854f07a40ef1c15e")
}
]
},
{
"_id" : ObjectId("56322117b61f07a40ef1c15d"),
"cars" : [
{
"carId" : "6G",
"_id" : ObjectId("51212929b64f07a40ef1c15e")
},
{
"carId" : "3C",
"_id" : ObjectId("51273329b64f07a40ef1c15e")
},
{
"carId" : "4N",
"_id" : ObjectId("51241279b64f07a40ef1c15e")
}
]
}
]
}
Please note that I have two nested arrays, and apparently MongoDb lacks when it comes to dealing with Projections with deep arrays. The $ operator can only be used once in a projection; leaving with no clues as how to to achieve this simple task.
So again I want to find --only-- the document that has "carId" : "3C" and only return the immediate obj containing the "carId" : "3C". but not the parent objects.
Any help would be so much appreciated. Possibly using either direct MongoDb or Mongoose. Mongoose would be preferred.
As for reference, I have already covered these other related issues wasn't able to figure it out.
Updating a deep record in MongoDb
How to Update Multiple Array Elements in mongodb
Hope in the future, this question and your solutions will help others.
Amir,
You must use the Aggregation Framework. You can build a pipeline that processes a stream documents through several building blocks: filtering, projecting,grouping,sorting,etc.
When dealing with nested arrays you will have to use the $unwind command. You can get what you want by doing the following.
db.cars.aggregate(
//De-normalized the nested array of accounts
{"$unwind": "$accounts"},
//De-normalized the nested array of cars
{"$unwind": "$accounts.cars"},
//match carId to 3C
{"$match": {"accounts.cars.carId" : "3C"}},
//Project the accoutns.cars object only
{"$project" : {"accounts.cars" : 1}},
//Group and return only the car object
{"$group":{"_id":"$accounts.cars"}}
).pretty();
You can use the aggregation framework for "array filtering" by using $unwind .
You can delete each line from the bottom of each command in the aggregation pipeline in the above code to observe the pipelines behavior.
Here's an example without the aggregation framework. I don't think there's a way purely from querying that you'll be able to get just the individual nested object you're looking for so you have to do a little post processing work. something like Mongoose may provide a way to do this but I'm not really up on what the Mongoose API's look like currently.
var doc = db.cars.findOne({"accounts.cars" : {$elemMatch: {"carId" : "3C"}}}, {"accounts.cars.$": 1, _id: 0})
var car = doc.accounts[0].cars[0]

MongoDB: updating an array in array

I seem to be having an issue accessing the contents of an array nested within an array in a mongodb document. I have no problems accessing the first array "groups" with a query like the following...
db.orgs.update({_id: org_id, "groups._id": group_id} , {$set: {"groups.$.name": "new_name"}});
Where I run into trouble is when I try to modify properties of an element in the array "features" nested within the "group" array.
Here is what an example document looks like
{
"_id" : "v5y8nggzpja5Pa7YS",
"name" : "Example",
"display_name" : "EX1",
"groups" : [
{
"_id" : "s86CbNBdqJnQ5NWaB",
"name" : "Group1",
"display_name" : "G1",
"features" : [
{
_id : "bNQ5Bs8BWqJn6CdNa"
type : "blog",
name : "[blog name]"
owner_id : "ga5YgvP5yza7pj8nS"
},
]
},
]
},
And this is the query I tried to use.
db.orgs.update({_id: "v5y8nggzpja5Pa7YS", "groups._id": "qBX3KDrtMeJGvZWXZ", "groups.features._id":"bNQ5Bs8BWqJn6CdNa" }, {$set: {"groups.$.features.$.name":"New Blog Name"}});
It returns with an error message:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 2,
"errmsg" : "Too many positional (i.e. '$') elements found in path 'groups.$.features.$.name'"
}
})
It seems that mongo doesn't support modifying arrays nested within arrays via the positional element?
Is there a way to modify this array without taking the entire thing out, modifying it, and then putting it back in? With multiple nesting like this is it standard practice to create a new collection? (Even though the data is only ever needed when the parent data is necessary) Should I change the document structure so that the second nested array is an object, and access it via key? (Where the key is an integer value that can act as an "_id")
groups.$.features.[KEY].name
What is considered the "correct" way to do this?
After some more research, it looks like the only way to modify the array within an array would be with some outside logic to find the index of the element I want to change. Doing this would require every change to have a find query to locate the index, and then an update query to modify the array. This doesn't seem like the best way.
Link to a 2010 JIRA case requesting multiple positional elements...
Since I will always know the ID of the feature, I have opted to revise my document structure.
{
"_id" : "v5y8nggzpja5Pa7YS",
"name" : "Example",
"display_name" : "EX1",
"groups" : [
{
"_id" : "s86CbNBdqJnQ5NWaB",
"name" : "Group1",
"display_name" : "G1",
"features" : {
"1" : {
type : "blog",
name : "[blog name]"
owner_id : "ga5YgvP5yza7pj8nS"
},
}
},
]
},
With the new structure, changes can be made in the following manner:
db.orgs.update({_id: "v5y8nggzpja5Pa7YS", "groups._id": "s86CbNBdqJnQ5NWaB"}, {$set: {"groups.$.features.1.name":"Blog Test 1"}});

Resources