I used MongoDb server version: 4.2.0.
I have Compound index MongoDB:
db.fop.createIndex( { "id":1, "ADDRESS": "text"})
It works:
db.fop.find({"id":{$in:[1]},$text: {$search: "AnyTextSearch"}}, {score: {$meta: "textScore"}}).sort({score:{$meta:"textScore"}})
This does not work:
db.fop.find({"id":{$in:[1,2]},$text: {$search: "AnyTextSearch"}}, {score: {$meta: "textScore"}}).sort({score:{$meta:"textScore"}})
I get an error:
Error: error: {
"ok" : 0,
"errmsg" : "error processing query: ns=osint.fopTree: $and\n id $in [ 1.0 2.0 ]\n TEXT : query=AnyTextSearch, language=english, caseSensitive=0, diacriticSensitive=0, tag=NULL\nSort: { score: { $meta: \"textScore\" } }\nProj: { score: { $meta: \"textScore\" } }\n planner returned error :: caused by :: failed to use text index to satisfy $text query (if text index is compound, are equality predicates given for all prefix fields?)",
"code" : 2,
"codeName" : "BadValue"}
How to make the right request?
Related
I have a collection with 300 million documents, each doc has a user_id field like following:
{
"user_id": "1234567",
// and other fields
}
I want to a list of unique user_ids in the collection, but the following mongo shell command results in an error.
db.collection.aggregate([
{ $group: { _id: null, user_ids: { $addToSet: "$user_id" } } }
], { allowDiskUse: true });
2021-11-23T14:50:28.163+0900 E QUERY [js] uncaught exception: Error: command failed: {
"ok" : 0,
"errmsg" : "Error on remote shard <host>:<port> :: caused by :: BSONObj size: 46032166 (0x2BE6526) is invalid. Size must be between 0 and 16793600(16MB) First element: _id: null",
"code" : 10334,
"codeName" : "BSONObjectTooLarge",
"operationTime" : Timestamp(1637646628, 64),
...
} : aggregate failed :
Why does the error occur even with allowDiskUse: true option?
The db version 4.2.16.
You try to insert all unique user_ids in single document , but apparently the size of this document become greater then16MB causing the issue.
distinct may be more useful
db.collection.distinct( "user_id" )
I am getting error while executing the following command in mongodb:
db.trans.aggregate(
[
{ $match: {"cno":89}},
{ $group: { _id: [ $dateToString: { format: "%Y-%m-%d", date: "$transactiondate" },types:"$type"], count: { $sum: 1 } } }])
I want to group by transaction date and type.
The error is:
assert: command failed: {
"ok" : 0,
"errmsg" : "this object is already an operator expression, and can't be used as a document expression (at 'types')",
"code" : 15990
} : aggregate failed_getErrorWithCode#src/mongo/shell/utils.js:25:13
doassert#src/mongo/shell/assert.js:16:14
assert.commandWorked#src/mongo/shell/assert.js:370:5
DBCollection.prototype.aggregate#src/mongo/shell/collection.js:1319:5
#(shell):1:1
2017-10-24T15:38:35.498+0530 E QUERY [thread1] Error: command failed: {
"ok" : 0,
"errmsg" : "this object is already an operator expression, and can't be used as a document expression (at 'types')",
"code" : 15990
} : aggregate failed :
_getErrorWithCode#src/mongo/shell/utils.js:25:13
doassert#src/mongo/shell/assert.js:16:14
assert.commandWorked#src/mongo/shell/assert.js:370:5
DBCollection.prototype.aggregate#src/mongo/shell/collection.js:1319:5
#(shell):1:1
One of my collection no longer returns anything on some search values. Here is a console dump to illustrate the probleme :
meteor:PRIMARY> db['test'].insert({ sku: 'Barrière' });
WriteResult({ "nInserted" : 1 })
meteor:PRIMARY> db['test'].insert({ sku: 'Bannière' });
WriteResult({ "nInserted" : 1 })
meteor:PRIMARY> db['test'].createIndex({ sku: 'text' });
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
meteor:PRIMARY> db['test'].find({ sku: /ba/i });
{ "_id" : ObjectId("57bbb447fc77800b1e63ba64"), "sku" : "Barrière" }
{ "_id" : ObjectId("57bbb455fc77800b1e63ba65"), "sku" : "Bannière" }
meteor:PRIMARY> db['test'].find({ $text: { $search: 'ba' } });
meteor:PRIMARY> db['test'].find({ $text: { $search: 'Ba' } });
meteor:PRIMARY>
The search returned nothing, even though I clearly added two documents that should match. What's going on? What option/config am I missing?
** Edit **
I tried this query
meteor:PRIMARY> db['test'].find({ $or: [ { $text: { $search: 'ba' } }, { sku: { $regex: 'ba', $options: 'i' } } ] });
Error: error: {
"waitedMS" : NumberLong(0),
"ok" : 0,
"errmsg" : "error processing query: ns=meteor.testTree: $or\n sku regex /ba/\n TEXT : query=ba, language=english, caseSensitive=0, diacriticSensitive=0, tag=NULL\nSort:
{}\nProj: {}\n planner returned error: Failed to produce a solution for TEXT under OR - other non-TEXT clauses under OR have to be indexed as well.",
"code" : 2
}
But I'm not sure how I can make an index to search partial values (i.e. using $regex or other operator). Using a third party indexer seems overkill to me... Surely there is a way to perform a full-text search, as well as a pattern match at once?
Is my only solution to perform two queries and merge the results manually?
Try this:
db['test'].insert({ sku: 'ba ba' });
db['test'].find({ $text: { $search: 'ba' } });
Also refer to mongodb document:
If the search string is a space-delimited string, $text operator performs a logical OR search on each term and returns documents that contains any of the terms.
I think mongodb $text $search just split the string by space and match the whole word. If you need to search part of the word, you may need to use some other framework for help. Maybe you can also use $regex to do this.
If the only requirement is to query the word by prefix, you can use $regex, it can use index if you are only querying by the prefix. Otherwise if will scan the whole collection.
I am trying to search for the word "credit" in my colloection suing the aggregation framework but I having an error. could anyone help figure out what the issue might be.
db.complaints.createIndex({issue:1})
db.complaints.aggregate([
{$match:{$text:{$search:"credit"}}},
{$project:{issue:1,_id:0}}
])
I am having this error:
assert: command failed: {
"errmsg" : "exception: error processing query: ns=customers.complaints l
imit=0 skip=0\nTree: TEXT : query=credit, language=, tag=NULL\nSort: {}\nProj: {
$textScore: { $meta: \"textScore\" }, issue: 1, _id: 0 }\n planner returned err
or: need exactly one text index for $text query",
"code" : 2,
"ok" : 0
} : aggregate failed
Error: command failed: {
"errmsg" : "exception: error processing query: ns=customers.complaints l
imit=0 skip=0\nTree: TEXT : query=credit, language=, tag=NULL\nSort: {}\nProj: {
$textScore: { $meta: \"textScore\" }, issue: 1, _id: 0 }\n planner returned err
or: need exactly one text index for $text query",
"code" : 2,
"ok" : 0
} : aggregate failed
at Error (<anonymous>)
at doassert (src/mongo/shell/assert.js:11:14)
at Function.assert.commandWorked (src/mongo/shell/assert.js:254:5)
at DBCollection.aggregate (src/mongo/shell/collection.js:1278:12)
at (shell):1:15
2015-09-01T17:10:45.512+0100 E QUERY Error: command failed: {
"errmsg" : "exception: error processing query: ns=customers.complaints l
imit=0 skip=0\nTree: TEXT : query=credit, language=, tag=NULL\nSort: {}\nProj: {
$textScore: { $meta: \"textScore\" }, issue: 1, _id: 0 }\n planner returned err
or: need exactly one text index for $text query",
"code" : 2,
"ok" : 0
} : aggregate failed
at Error (<anonymous>)
at doassert (src/mongo/shell/assert.js:11:14)
at Function.assert.commandWorked (src/mongo/shell/assert.js:254:5)
at DBCollection.aggregate (src/mongo/shell/collection.js:1278:12)
at (shell):1:15 at src/mongo/shell/assert.js:13
If you take a look at your error message then you will see the following message: need exactly one text index for $text query.
Your post shows that you did create an index on issue. However, it appears that you do not have a Text Index declared for your collection.
If you want the issue document field to be text searchable then create a text index as follows:
db.complaints.createIndex({issue:"text"})
(Note, you may only have one text index per collection. However, the fields included in the text index are established upon index creation. Again, see the abovementioned Text Index link.)
This query will work:
db.things.aggregate([{$match:{issue:"credit"}},{$project:{issue:1,_id:0}}])
I am using mongoDb 2.6.4 and still getting an error:
uncaught exception: aggregate failed: {
"errmsg" : "exception: aggregation result exceeds maximum document size (16MB)",
"code" : 16389,
"ok" : 0,
"$gleStats" : {
"lastOpTime" : Timestamp(1422033698000, 105),
"electionId" : ObjectId("542c2900de1d817b13c8d339")
}
}
Reading different advices I came across of saving result in another collection using $out. My query looks like this now:
db.audit.aggregate([
{$match: { "date": { $gte : ISODate("2015-01-22T00:00:00.000Z"),
$lt : ISODate("2015-01-23T00:00:00.000Z")
}
}
},
{ $unwind : "$data.items" } ,
{
$out : "tmp"
}]
)
But I am getting different error:
uncaught exception: aggregate failed:
{"errmsg" : "exception: insert for $out failed: { lastOp: Timestamp 1422034172000|25, connectionId: 625789, err: \"insertDocument :: caused by :: 11000 E11000 duplicate key error index: duties_and_taxes.tmp.agg_out.5.$_id_ dup key: { : ObjectId('54c12d784c1b2a767b...\", code: 11000, n: 0, ok: 1.0, $gleStats: { lastOpTime: Timestamp 1422034172000|25, electionId: ObjectId('542c2900de1d817b13c8d339') } }",
"code" : 16996,
"ok" : 0,
"$gleStats" : {
"lastOpTime" : Timestamp(1422034172000, 26),
"electionId" : ObjectId("542c2900de1d817b13c8d339")
}
}
Can someone has a solution?
The error is due to the $unwind step in your pipeline.
When you unwind by a field having n elements, n copies of the same documents are produced with the same _id. Each copy having one of the elements from the array that was used to unwind. See the below demonstration of the records after an unwind operation.
Sample demo:
> db.t.insert({"a":[1,2,3,4]})
WriteResult({ "nInserted" : 1 })
> db.t.aggregate([{$unwind:"$a"}])
{ "_id" : ObjectId("54c28dbe8bc2dadf41e56011"), "a" : 1 }
{ "_id" : ObjectId("54c28dbe8bc2dadf41e56011"), "a" : 2 }
{ "_id" : ObjectId("54c28dbe8bc2dadf41e56011"), "a" : 3 }
{ "_id" : ObjectId("54c28dbe8bc2dadf41e56011"), "a" : 4 }
>
Since all these documents have the same _id, you get a duplicate key exception(due to the same value in the _id field for all the un-winded documents) on insert into a new collection named tmp.
The pipeline will fail to complete if the documents produced by the
pipeline would violate any unique indexes, including the index on the
_id field of the original output collection.
To solve your original problem, you could set the allowDiskUse option to true. It allows, using the disk space whenever it needs to.
Optional. Enables writing to temporary files. When set to true,
aggregation operations can write data to the _tmp subdirectory in the
dbPath directory. See Perform Large Sort Operation with External Sort
for an example.
as in:
db.audit.aggregate([
{$match: { "date": { $gte : ISODate("2015-01-22T00:00:00.000Z"),
$lt : ISODate("2015-01-23T00:00:00.000Z")
}
}
},
{ $unwind : "$data.items" }] , // note, the pipeline ends here
{
allowDiskUse : true
});