I ask one simple solution and want to extend it with some functionalities.
Here is my shorter question: Filter an empty collection
The question now is how to extend this RSQL query without extra efford of second request?
Data Model:
{
"test":[
{
"id":"252355",
"deleted":false,
"properties":[
{
"id":"sgdegegwe",
"deleted":false
},
{
"id":"aaaaa",
"deleted":true
}
]
},
{
"id":"252555",
"deleted":false,
"properties":[
]
}
]
}
The Result should be
{
"test":[
{
"id":"252355",
"deleted":false,
"properties":[
{
"id":"sgdegegwe",
"deleted":false
}
]
},
{
"id":"252555",
"deleted":false,
"properties":[
]
}
]
}
My solution so far is to to get a result for the first test entity is to rewrite the query and ask at properties endpoint with linking to test-id. But dont get the result I want, so I ask the linked question at first and now how to combine and simplify request.
I want to use RSQL because there should be also an option to see all properties, with
properties.deleted=in=(true,false)
Related
Assume we have following collection.
{
"Region":"Karnataka",
"ShortCode":"KA",
"SubRegion":[
{
"District":"Banglore",
"Commodity":[
{
"Name":"items",
"isActive":true,
"CommoditySubType":[
{
"Title":"Moistouriser",
"isActive":true,
"hasGrades":true,
"Grade":[
{
"Title":"Premium",
"Rate":"150",
"isActive":true,
"hasRates":true,
"hasSizes":true,
"StartDate":"2021-03-31",
"EndDate":"2021-04-06",
"StartTime":"9:00am",
"EndTime":"6:00pm",
"Sizes":[
{
"Title":"Small",
"isActive":true
}
]
"LastSevenDaysDates":[{
"Date":2021-03-31,
"Price":"150"
}]
}
]
}
]
}
]
},
{
"District":"Coorg",
"Commodity":[]
}
] }
I want to update an object under LastsevndayDates. I tried this.
mongo.db.supplierDailyPrice.update(
{
"Region":region,
"SubRegion.District":district,
"SubRegion.Commodity.Name":commodity,
"SubRegion.Commodity.CommoditySubType.Title":commoditysubtype,
"$and": [
{ "SubRegion.Commodity.CommoditySubType.Grade": { "$exists": True}},
{ "SubRegion.Commodity.CommoditySubType.Grade.Title": "Premium" },
]
},
{
"$set": {
"SubRegion.$[].Commodity.$[].CommoditySubType.$[].Grade.$[].LastSevenDaysDates": Date
}
})
But it's failing with the error pymongo.errors.WriteError: The path 'SubRegion.0.Commodity.0.CommoditySubType.1.Grade' must exist in the document in order to apply array updates.
You can use arrayFilters to solve your problem
db.supplierDailyPrice.update({
"Region":region
},
{
$set:{
"Subregion.$[sub].Commodity.$[com].CommoditySubType.$[Cst].Grade.$[grd]. LastSevenDaysDates.$[sev].date": Date
}
},
{
array_filter : [
{"sub.district": district},
{"com.name": commodity},
{"Cst.title": commoditysubtype},
{"grd.title": "premium"},
{"sev.price":"150"},
]
})
Not tested the code but something like this will solve your problem. For more reference you can check out the links below:
Update deeply nested array in mongodb
update deeply nested array mongodb
Pymongo error for ArrayFilters to update multiple subdocuments
Ujjwal's answer is on the right track. I fixed a few typos.
More information here about $[] usage.
https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/
https://developer.mongodb.com/how-to/update-array-elements-document-mql-positional-operators/
db.supplierDailyPrice.update_one({
"Region": region
},
{
$set:{
"SubRegion.$[sub].Commodity.$[com].CommoditySubType.$[cst].Grade.$[grd].LastSevenDaysDates.$[sev].Date": "2021-04-03"
}
},
{
"array_filters" : [
{"sub.District": district},
{"com.Name": commodity},
{"cst.Title": commoditysubtype},
{"grd.Title": grade},
{"sev.Price":"150"},
]
},
{
upsert=true
}
)
I want to do crud operations on about 1000 documents.
using a loop and insert 1 by 1 is fine, but there is a better aka faster way?
like for example in Postgres I can use generate_series() for that purpose, and what about Mongo?
As prasad wrote in the comments above, you can use insertMany(). You would write a loop to generate the documents and store them in an array. Then you could pass that array of documents to db.collection.insertMany().
Another option would be to use bulkWrite. You could write a loop to generate an array of the operations you want to insert. For example:
[
{ insertOne: { "document": { "name": "Gal", "hobbies": ["reading", "gaming" ] } } },
{ insertOne: { "document": { "name": "Gal", "hobbies": ["reading", "gaming" ] } } },
...
]
Then you would pass that array to bulkWrite:
try {
db.characters.bulkWrite(myArray);
} catch (e) {
print(e);
}
I have a not so unique requirement but i am just finding the right terminology to search, since i only keep getting results on how to query list/ array fields or nested elements.
Here is my class (document type)...
public class Item {
private String identity = null;
private String name = null;
private String type = null;
private List<Item> grouping = null;
}
Thus, some entity instances of this type could get complex as shown below...
{
"identity":"ITEM-1",
"name":"Pack-1",
"type":"Bundle",
"grouping":[
{
"identity":"ITEM-2",
"name":"Book",
"type":"Atomic Unit"
},
{
"identity":"ITEM-3",
"name":"Stationary",
"type":"Bundle",
"grouping":[
{
"identity":"ITEM-4",
"name":"Pen",
"type":"Atomic Unit"
},
{
"identity":"ITEM-5",
"name":"Paper",
"type":"Atomic Unit"
},
{
"identity":"ITEM-6",
"name":"Paraphernalia",
"type":"Bundle",
"grouping":[
{
"identity":"ITEM-7",
"name":"Eraser",
"type":"Atomic Unit"
},
{
"identity":"ITEM-8",
"name":"Ruler",
"type":"Atomic Unit"
},
{
"identity":"ITEM-9",
"name":"Compass",
"type":"Atomic Unit"
}
]
}
]
}
]
}
Now my requirement is to be able to search for Book or Pen or Compass and must be able to fetch the record ITEM-1. How do I achieve this in Mongo Query. I am using Spring Data Mongo Repository approach on my data abstraction service layer.
Thanks in advance for all the help.
my requirement is to be able to search for Book or Pen or Compass and
must be able to fetch the record ITEM-1.
You can try this query from mongo shell, and it fetches the document:
var SEARCH_ITEMS = [ "Book", "Pen", "Compass" ]
var ATOMIC = "Atomic Unit"
db.collection.find( {
$or: [
{ "type": ATOMIC, name: { $in: SEARCH_ITEMS } },
{ "grouping.type": ATOMIC, "grouping.name": { $in: SEARCH_ITEMS } },
{ "grouping.grouping.type": ATOMIC, "grouping.grouping.name": { $in: SEARCH_ITEMS } },
{ "grouping.grouping.grouping.type": ATOMIC, "grouping.grouping.grouping.name": { $in: SEARCH_ITEMS } }
]
} )
i am trying to read only matching keys from a JSON with a nested array.
here is my JSON.
data:[
{
"locale":"en_US",
"pages":[
{
pageName:"testpage1",
"messages":{
"m1":"v1",
"m2":""
}
},
{
pageName:"testpage2",
"messages":{
"m1":"v3",
"m2":"v4"
}
}
]
},
{
"locale":"in_L1",
"pages":[
{
pageName:"testpage1",
"messages":{
"m1":"i1",
"m2":"i2"
}
},
{
pageName:"testpage2",
"messages":{
"m1":"i3",
"m2":"i4"
}
}
]
}
]
I am trying the below query:
db['collec1'].find({locale:"en_US", pages:{$elemMatch:{pageName:"testpage1"},
{locale:1,"pages.pageName":1}}})
also tried,
db['collec1'].find({locale:"en_US", "pages.pageName":"testpage1"},{locale:1,"pages.pageName":1}}})
both are returning, the all the elements in the array as below:
[
{
"locale":"en_US",
pages:{pageName:["testpage1", "testpage2"]}]
}
]
Expected output is:
[
{
"locale":"en_US",
pages:{pageName:["testpage1"]}]
}
]
can someone help me where i am doing it wrong and what needs to be changed?
i am using this library which is a clone of mongodb called Ne DB.
db['collec1'].find({locale:"en_US", pages:{$elemMatch:{pageName:"testpage1"}}).
try with an empty project in the find method {} and then try like
the above example
I am sending the following commands with
my $url = "http://xxxxx/solr/inventory/update?commitWithin=1000";
I am using perl to send to a solr setup on another server.
Please excuse the formatting. I really did try.
Thanks
Mike
RESULTING DATA - The data from the first command is not here. All subsequent calls are.
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"*:*",
"fq":"id:3-159682",
"_":"1529984183431"
}
},
"response":{
"numFound":1,
"start":0,
"docs":[
{
"checklist_id":249746,
"brand_s":"Pinnacle",
"featured":"",
"sf_set_sort":"Baseball1992Pinnacle",
"sf_set_sort_s":"Baseball1992Pinnacle",
"sport_s":"Baseball",
"cardnumber":"308",
"issue_s":"",
"id":"3-159682",
"year_s":"1992",
"team":"Los Angeles Dodgers",
"set_name_s":"",
"has_image":1,
"amazon_sku":"159682",
"amazon_sync":1,
"sf_id":378827,
"sf_ending_time":2222222222,
"sf_sort_id":199230875,
"sf_listing_type":"buy",
"shopify_id":"1302493397094",
"_version_":1604345060355211264
}
]
}
}
COMMANDS AND RESPONSES
[
{
"inv_location":"",
"ean":"",
"site_id":"3",
"category_id":[
"1",
"55",
"2162220",
"2715086",
"306",
"2352370",
"2413461"
],
"cp_id":"159682",
"isbn":"",
"id":"3-159682",
"consigner":"",
"upc_code":"0",
"quantity":"1",
"created_date":"2018-06-26T10:17:55Z",
"mpn":"",
"description":"",
"inv_num":"",
"cp_listing_type":"1",
"price":"0.69",
"title":"1992 Pinnacle #308 Darryl Strawberry NM-MT ",
"live_status":""
}
]
Success: {
"responseHeader":{
"status":0,
"QTime":1
}
}
[
{
"checklist_id":"249746",
"brand_s":"Pinnacle",
"featured":"",
"sf_set_sort":"Baseball1992Pinnacle",
"sport_s":"Baseball",
"cardnumber":"308",
"issue_s":"",
"id":"3-159682",
"year_s":"1992",
"team":"Los Angeles Dodgers",
"set_name_s":""
}
]
Success: {
"responseHeader":{
"status":0,
"QTime":1
}
}
[
{
"has_image":{
"set":"1"
},
"id":"3-159682"
}
]
Success: {
"responseHeader":{
"status":0,
"QTime":1
}
}
[
{
"amazon_sku":{
"set":"159682"
},
"amazon_sync":{
"set":"1"
},
"id":"3-159682"
}
]
Success: {
"responseHeader":{
"status":0,
"QTime":1
}
}
[
{
"sf_id":{
"set":"378827"
},
"sf_ending_time":{
"set":"2222222222"
},
"sf_sort_id":{
"set":"199230875"
},
"id":"3-159682",
"sf_listing_type":{
"set":"buy"
}
}
]
Success: {
"responseHeader":{
"status":0,
"QTime":1
}
}
[
{
"id":"3-159682",
"shopify_id":{
"set":"1302493397094"
}
}
]
Success: {
"responseHeader":{
"status":0,
"QTime":1
}
}
The two documents you submit have the same id. The second document overwrites the first one, since the id has to uniquely identify a document. If the id doesn't do that, change which field is defined as a uniqueKey, or use a UUID generator to get a new id each time the document is submitted. The latter will cause issues if you're trying to do updates without having the new uuid readily available, tho.
Another solution would be to prefix the id with the document type, or (depending on your use case) merge it into a single document before indexing.
The answer to my problem was that the 1st and 2nd commands were full updates, and the rest were partial updates (using "set"
I change the second command to a format like this
[{"checklist_id":{"set":"249725"},"brand_s":{"set":"Pinnacle"},"featured":{"set":""},"sf_set_sort":{"set":"Baseball1992Pinnacle"},"sport_s":{"set":"Baseball"},"cardnumber":{"set":"287"},"issue_s":{"set":""},"id":"3-159694","year_s":{"set":"1992"},"team":{"set":"Milwaukee Brewers"},"set_name_s":{"set":""}}]
And all was right with the code, no lionger overwriting the first query.
Maybe this will help someone else!
Thanks
Mike