Mongo text search doesn't fetch results for keyword "How" - mongodb

I have mongo documents as follows,
{
"_id" : ObjectId("5b5ff3ec6df1fc21dc206d12"),
"activityName" : "How sensor",
"timeZone" : "+05.30",
"venue" : "130 E San Fernando St #154, San Jose, CA 95112, USA",
"activityState" : "Active",
"activityType" : "campaign",
"commentTheme" : "59c26fb3fd9a8e79242fe210",
"commentEnabled" : false,
"startTimeStamp" : 1532602800000.0,
"endTimeStamp" : 2164186800000.0
}
And there is a text index created on filed activityName as follows,
`db.ActivityDetails.createIndex( { 'activityName':'text' } );`
But for the text search keyword how it doesn't output given document as results. Does anyone knows a possible reason for this behaviour. My query is as follows,
db.getCollection('ActivityDetails').find({ $text: { $search: "how" } })
but for the word sensor, it gives the correct results. Appreciate any help

'how' is a stop word in English It is ignored in text index and can't be searched.
You can experiment with {default_language: 'none'} which will not use any stop words, but it won't use steming either, so sensor won't match sensors.

Related

Query on all descendants of node

Given a collection of MongoDb documents with a property "myContacts" like this:
{
"_id": 123,
"myContacts" : {
"contacts" : {
"10" : {
"_id" : NumberLong(10),
"name" : "c1",
"prop" : true
},
"20" : {
"_id" : NumberLong(20),
"name" : "c2"
},
}
}
}
I want to select all documents, where at least one contact lacks the "prop" field.
I figured out a general query:
db.getCollection('xyz').find({ 'myContacts.contacts.???.prop': { $exists: false } })
The problem is that IDs of the contacts are part of the path and I cannot know them ahead. I want sth like 'myContacts.contacts.$anyChild.prop', but cannot find sth similar in the mongo docs.
Does it mean there is no way to do it?
PS: I cannot change the document structure, a live app uses it. I've spent some time with Google and my bet it's not possible. I however would like an opinion from people who have experience with Mongo.
Thank you guys for helpful comments, this got me going! I could get the results I wanted with:
db.getCollection('xyz').aggregate([{$project: {_id:1, contacts:{$objectToArray: "$myContacts.contacts"}}}, {$match: {"contacts.v.prop" : null}}])

(MongoDB) Aggregate (.out) moove values to wrong fields

I'm actually creating an autocomplete website bar using express js & mongodb 4.2.7, and using lat & lon to avoid using geocoding api.
Here is the format of my db:
{
"_id" : ObjectId("5eea03e9a7891b6d701df571"),
"id_ban_position" : "ban-position-4c882de48d894fc49ed9be76f7631d6d",
"id_ban_adresse" : "ban-housenumber-78a2651ce382476ca9c8c8fcbcbaa539",
"cle_interop" : "01001_A028_5307",
"id_ban_group" : "ban-group-37c7c3f2b61440b48bca7d8fad56055e",
"id_fantoir" : "01001A028",
"numero" : 5307,
"suffixe" : "",
"nom_voie" : "Lotissement les Lilas",
"code_postal" : 1400,
"nom_commune" : "L'Abergement-Clémenciat",
"code_insee" : 1001,
"nom_complementaire" : "",
"x" : 848436.205131189,
"y" : 6562595.33916435,
"lon" : 4.923279,
"lat" : 46.146903,
"typ_loc" : "parcel",
"source" : "dgfip",
"date_der_maj" : "2019-02-12"
}
as you can see, i got lot of fields that are not necessary for the purpose of my website, and most of all, i don't need to get one row for each number in a street, one unique name of street is enough. So i decided to supress duplicate street name ('nom_voie') and town name ('nom_commune') with aggregate as follow:
db.Addresses.aggregate(
[ {
$group: {
_id: {voie: "$nom_voie", commune: "$nom_commune"},
doc: {$first: "$$ROOT"}
}
},
{$replaceRoot: {newRoot: "$doc"}},
{$out: 'UniqueIds'}
],
{allowDiskUse: true }
);
The problem is that this utilisation mooved a lot of values from one field to an other and made my db absolutely unusable.
{
"_id" : ObjectId("5eea03e9a7891b6d701df571"),
"nom_voie" : "-",
"code_postal" : 1400,
"nom_commune" : "Lotissement les Lilas",
"nom_complementaire" : "",
"lon" : 6562595.33916435,
"lat" : 848436.205131189,
"field19" : "dgfip",
...
}
As you can see, the value of "nom_voie" is now in "nom_commune", "x" value is in "lat", and "y" value is in "lon" and finally the "nom_voie" value is now "-", and i got new fields replacing others ("field19" for "source")...
Am i using aggregate with a wrong option?
I got 47 Millions entry, is this creating some issues?
Thanks to all of you for your time, even if you just reading this!
EDIT :
After few tries and some search i found out that it is the aggregate function that create some problems, but i still don't understand why, if somebody got some hints, i just edited the doc so it's more understandable and readable!
(I thought before that it was a $unset problem in a function)

reserved words (Where, from , and) in full text search query in mongo db

I am using mongodb, I am stucked on a issue :
Data is :
{
"_id" : ObjectId("5a956e0b78d363d37f6a2ec4"),
"fieldType" : "Enter Source",
"value" : "Delhi",
"catgeory" : "Generic",
"synonym" : [
"origin name or code",
"from",
"enter source",
"from where",
"fro wher"
]
}
When I use this query
db.getCollection("Rules_DefaultValue").find(
{
"synonym" : "from where"
});
I got correct result as expected
But when I use this query
db.getCollection("Rules_DefaultValue").find(
{
"$text" : {
"$search" : "where"
}
});
I didn't got any result , So I changed it again
db.getCollection("Rules_DefaultValue").find(
{
"$text" : {
"$search" : "wher"
}
});
and this time it worked.
So I came to a conclusion that "where" is reserve keyword and I can't use it as it is. So I tried with escape char :
"$search" : "\"where\""
but again I did'nt got the result.
same thing is happening with
and , from , *
Please help me on this , How can I make query with these words.
Words like where and from are considered as stopwords in MongoDB. It means that when you create a text index those words are wiped out from the index since they appear very frequently in English while the point of FTS is to index some words that allow you to easily find the document you're looking for. To fix that you can create your text index specifying language to none, try:
db.getCollection("Rules_DefaultValue").createIndex(
{ synonym : "text" },
{ default_language: "none" }
)
Then your query should return the document mentioned in your post.

I have big database on mongodb and can't find and use my info

This my code:
db.test.find() {
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"title" : "Sir",
"name" : {
"_id" : ObjectId("4d3ed089fb60ab534684b7ff"),
"first_name" : "Farid"
},
"addresses" : [
{
"city" : "Baku",
"country" : "Azerbaijan"
},{
"city" : "Susha",
"country" : "Azerbaijan"
},{
"city" : "Istanbul",
"country" : "Turkey"
}
]
}
I want get output only all city. Or I want get output only all country. How can i do it?
I'm not 100% about your code example, because if your 'find' by ID there's no need to search by anything else... but I wonder whether the following can help:
db.test.insert({name:'farid', addresses:[
{"city":"Baku", "country":"Azerbaijan"},
{"city":"Susha", "country":"Azerbaijan"},
{"city" : "Istanbul","country" : "Turkey"}
]});
db.test.insert({name:'elena', addresses:[
{"city" : "Ankara","country" : "Turkey"},
{"city":"Baku", "country":"Azerbaijan"}
]});
Then the following will show all countries:
db.test.aggregate(
{$unwind: "$addresses"},
{$group: {_id:"$country", countries:{$addToSet:"$addresses.country"}}}
);
result will be
{ "result" : [
{ "_id" : null,
"countries" : [ "Turkey", "Azerbaijan"]
}
],
"ok" : 1
}
Maybe there are other ways, but that's one I know.
With 'cities' you might want to take more care (because I know cities with the same name in different countries...).
Based on your question, there may be two underlying issues here:
First, it looks like you are trying to query a Collection called "test". Often times, "test" is the name of an actual database you are using. My concern, then, is that you are trying to query the database "test" to find any collections that have the key "city" or "country" on any of the internal documents. If this is the case, what you actually need to do is identify all of the collections in your database, and search them individually to see if any of these collections contain documents that include the keys you are looking for.
(For more information on how the db.collection.find() method works, check the MongoDB documentation here: http://docs.mongodb.org/manual/reference/method/db.collection.find/#db.collection.find)
Second, if this is actually what you are trying to do, all you need to for each collection is define a query that only returns the key of the document you are looking for. If you get more than 0 results from the query, you know documents have the "city" key. If they don't return results, you can ignore these collections. One caveat here is if data about "city" is in embedded documents within a collection. If this is the case, you may actually need to have some idea of which embedded documents may contain the key you are looking for.

indexing vs normalization when optimizing for read speed

Having an architecture discussion with a coworker and we need to find an answer for this. Given a set of millions of data points that look like:
data =
[{
"v" : 1.44,
"tags" : {
"account" : {
"v" : "1055",
"name" : "Circle K"
}
"region" : "IL-East"
}
}, {
"v" : 2.25,
"tags" : {
"account" : {
"v" : "1055",
"name" : "Circle K"
}
"region" : "IL-West"
}
}]
and that we need to query on the fields in the tags collection (e.g. where account.name == "Circle K"), would there be any speed benefit to normalizing the account field to this:
accounts =
[{
_id : 507f1f77bcf86cd799439011,
v: "1055",
name : "Circle K"
}]
data =
[{
"v" : 1.44,
"tags" : {
"account" : 507f1f77bcf86cd799439011
"region" : "IL-East"
}
}, {
"v" : 2.25,
"tags" : {
"account" : 507f1f77bcf86cd799439011
"region" : "IL-West"
}
}]
I suspect I'll have to build 2 db's for this and just see what the speed looks like. The question is, is mongo better at querying on BSON IDs vs. strings? The db in question will be about 1:10 write vs. read.
The most important thing here is to make sure that you have enough RAM for your working set. That includes the space for the "tags.account.name" index and the expected query result set.
As for the key size. You use ObjectID-as-string above, which you should not do. Leave the real ObjectIDs in as their size is quite a bit smaller. If you really have a lot of small documents, then you might even want to think about shorting your field names as well.