In the MongoDB Documentation we've got the following example:
db.factories.insert( { name: "xyz", metro: { city: "New York", state: "NY" } } );
db.factories.ensureIndex( { metro : 1 } );
// this query can use the above index:
db.factories.find( { metro: { city: "New York", state: "NY" } } );
I'm currently looking for a solution to archieve this query in spring data. My first approach was
Query.query(Criteria.where("metro")
.andOperator(Criteria.where("city").is("New York")
.and("state").is("NY")))
but this results in the following query
{ "metro" : { } , "$and" : [ { "city" : "New York" , "state" : "NY"}]}
Finally i found the solution by fiddling around:
Query.query(Criteria.where("metro").is(
Query.query(
Criteria.where("city").is("New York")
.and("state").is("NY")).getQueryObject()
)
)
// results in { metro: { city: "New York", state: "NY" } }
Hopefully this is the right way to do it...
Related
I'm new to MongoDB and was looking through the docs a few nights ago and saw something that I haven't been able to locate since...
There was an option, I believe it was related to $text search, to treat an array of strings as if they were the same word. The syntax looked something like this:
["cheez", "cheese"],
["donut", "doughnut"],
["chips", "fries", "crisps"],
So a search for "chips" would return all documents indexed with "fries" or "crisps" even if they did not also have "chips".
Please tell me I wasn't dreaming!
YOU ARE NOT DREAMING
mongodb fuzzy text search
The following query searches the title field for the phrase naw yark. It uses the fuzzy default options where:
maxEdits allows up to two character variation of each term in the
given phrase to match the query to a document.
maxExpansions considers up to fifty similar terms for each term in
naw yark to find matches.
prefixLength is disabled.
The query also includes a $limit stage to limit the output to 10 results and a $project stage to:
Exclude all fields except title
Add a field named score
db.movies.aggregate([
{
$search: {
"text": {
"path": "title",
"query": "naw yark",
"fuzzy": {}
}
}
},
{
$limit: 10
},
{
$project: {
"_id": 0,
"title": 1,
score: { $meta: "searchScore" }
}
}
])
The above query returns the following results:
{ "title" : "New York, New York", "score" : 4.392756462097168 }
{ "title" : "New York", "score" : 4.050914287567139 }
{ "title" : "New York Stories", "score" : 3.4838104248046875 }
{ "title" : "New York Minute", "score" : 3.4838104248046875 }
{ "title" : "Synecdoche, New York", "score" : 3.4838104248046875 }
{ "title" : "New York Doll", "score" : 3.4838104248046875 }
{ "title" : "Little New York", "score" : 3.4838104248046875 }
{ "title" : "Escape from New York", "score" : 3.0559897422790527 }
{ "title" : "King of New York", "score" : 3.0559897422790527 }
{ "title" : "Naked in New York", "score" : 3.0559897422790527 }
also synonyms:
mongodb synonyms text search
For a given document, I am attempting to set a field (string) as the first element of an array of strings. Consider a collection myPlaces with the following document:
{
"name" : "Place Q",
"images" : [
"foo-1",
"foo-2",
"foo-3"
]
}
I am looking to create the following:
{
"name" : "Place Q",
"images" : [
"foo-1",
"foo-2",
"foo-3"
],
"image" : "foo-1"
}
So in the mongo shell, I execute:
db.myPlaces.update(
{
name: "Place Q"
},
{
$set:
{
image: images.0
}
}
)
This throws the error SyntaxError: missing } after property list which I don't understand. If I enclose the array in quotes "images.0" the value of image is set as "images.0", not "foo-1".
I've been reviewing the Mongodb documentation and see a lot of different examples but not something that makes clear to me what is probably a simple syntax for accessing an array value.
The following query works on MongoDB 4.2, It might not work on previous versions.
db.myPlaces.update(
{
name: "Place Q"
},
[
{
$set: {
image: {
$arrayElemAt: ["$images",0]
}
}
}
]
)
It's also very efficient as it is using $set pipeline provided in MongoDB 4.2+ versions.
Can you try this please :
db.myPlaces.update(
{
name: "Place Q"
},{
$set:
{
image: db.myPlaces.find( { "images.0" } )
}
}
)
Here what you can do is:
Find the document first.
Iterate on that (You must have only one value, but it will work for multiple documents as well)
Update document.
Note:- Efficient for the small records. Bulk record will have lots of traffic on DB.
===== Will work for all version of MongoDB ======
Data Before:
{
"_id" : ObjectId("5d53fda5f5fc3d6486b42fec"),
"name" : "Place Q",
"images" : [
"foo-1",
"foo-2",
"foo-3"
]
}
Query:
db.collection.find({ name: "Place Q" }).forEach(function(document) {
db.collection.update(
{},
{ "$set": { "image": document.images[0] } }
);
})
Data After
{
"_id" : ObjectId("5d53fda5f5fc3d6486b42fec"),
"name" : "Place Q",
"images" : [
"foo-1",
"foo-2",
"foo-3"
],
"image" : "foo-1"
}
Below the data structure of my services in MongoDB:
"serviceInfo" : {
"title" : "Lorem ipsum",
"options" : [
{
"startDate" : ISODate("2018-10-01T00:00:00.000Z"),
"endDate" : ISODate("2018-10-31T00:00:00.000Z"),
"availabilities" : [
{
"businessDay" : {
"id" : 1,
"name" : "Monday"
},
}
]
}
]
Now, I want to query all the services available the Monday during the period between startDate and endDate.
I tried this code but I have an empty array as result instead of my document.
db.collection('services').find({
'serviceInfo.options': {
$elemMatch: {
'startDate': { $lte: new Date(req.query.date) },
'endDate': { $gte: new Date(req.query.date) },
'availabilities': {
$elemMatch: {
'businessDay.id': req.query.day
}
}
}
}
}).toArray()
I guess my problem is in the nested array availabilities but I don't find the correct way to do the query.
Thanks in advance for your help.
I found my problem.
'businessDay.id' expected an Int32 and parseInt(req.query.day) did the trick.
I have the following document with this array:
"r" : [{
"id" : "890",
"ca" : "Other CPF Schemes and Priorities",
"su" : "National Day Rally 2015"
}, {
"id" : "1031-52347",
"ca" : "Current Events",
"su" : "Lee Kuan Yew"
}]
and I would like to list all documents where the id has got a dash so document with "id" : "1031-52347" will be returned.
I tried this:
{
r: { id: { $in: [/^-/] } }
}
but not able to get anything.
What would be the correct syntax?
I used this regex:
^[0-9]+-[0-9]+$
Debuggex Demo
You should try this database query:
"r":
{
{ "id": {"$regex" : new RegExp("^[0-9]+-[0-9]+$") } }
}
UPDATE
Working database queries by Blakes Seven
db.mydb.find({ "r.id": { "$regex": "^[0-9]+-[0-9]+$" }})
or
db.mydb.find({ "r.id": /^[0-9]+-[0-9]+$/ })
For the following data (taken from MongoDB in Action), how can I query in Mongo Shell to get the addresses.street for any document (in my case it's only 1 here) where the addresses.home equals "home"?
Desired result: {"street" : "1 E. 23rd Street"}
{ _id: ObjectId("4c4b1476238d3b4dd5000001")
username: "kbanker",
addresses: [
{
name: "home",
street: "588 5th Street",
city: "Brooklyn",
state: "NY",
zip: 11215},
{
name: "work",
street: "1 E. 23rd Street",
city: "New York",
state "NY",
zip 10010},
]}
You have to use $elemMatch in projection mode : DOCS
db.collection.find({},{addresses: {$elemMatch:{'name':'home'}}, 'addresses.street':1, _id:0})
{ "addresses" : [ { "street" : "588 5th Street" } ] }