Mongo - Array query, only find where all elements match - php

I'm trying to create a mongo query which will return results where all arrays have a specific element set to false.
An example data record :-
images: [
{
id: ObjectId("516bef7fc05e877b31000000"),
primary: true
},
{
id: ObjectId("516bef2ac05e879622000000"),
primary: false
},
{
id: ObjectId("516beeb7c05e879e2a000000"),
primary: false
}
],
name: "test",
etc: "etc"
I only wish to find documents where all primary fields are set to false however normally (using no query selectors or elemMatch) mongo will return this document because at least 1 of the array elements match.
How would I make mongo only return documents where they all match my search parameters?
Many thanks.

You can do this with the aggregation framework quite easily:
db.so.aggregate( [
{ $unwind: "$images" },
{ $group: {
_id: '$_id',
all: { $sum: 1 },
all_primary: { $sum: { $cond: [ { $eq: [ '$images.primary', true ] }, 1, 0 ] } },
images: { $push: '$images' },
name: { $first: '$name' },
etc: { $first: '$etc' },
} },
{ $project: {
_id: 1,
images: 1,
name: 1,
etc: 1,
same: { $cond: [ { $eq: [ '$all', '$all_primary' ] }, 1, 0 ] }
} },
{ $match: { 'same' : 1 } }
] );
With this as input:
{
"_id" : ObjectId("5203730bf8eaa52a846ebc3e"),
"images" : [
{
"id" : ObjectId("516bef7fc05e877b31000000"),
"primary" : true
},
{
"id" : ObjectId("516bef2ac05e879622010000"),
"primary" : true
},
{
"id" : ObjectId("516beeb7c05e879e2a000010"),
"primary" : true
}
],
"name" : "Derick",
"Etc" : true
}
{
"_id" : ObjectId("52037315f8eaa52a846ebc3f"),
"images" : [
{
"id" : ObjectId("516bef7fc05e877b31000000"),
"primary" : true
},
{
"id" : ObjectId("516bef2ac05e879622010000"),
"primary" : true
},
{
"id" : ObjectId("516beeb7c05e879e2a000020"),
"primary" : false
}
],
"name" : "James",
"Etc" : true
}
{
"_id" : ObjectId("520373621a78238235b6ffbf"),
"images" : [
{
"id" : ObjectId("516bef7fc05e877b31000000"),
"primary" : true
},
{
"id" : ObjectId("516bef2ac05e879622010000"),
"primary" : true
},
{
"id" : ObjectId("516beeb7c05e879e2a000020"),
"primary" : false
}
],
"name" : "James",
"etc" : true
}
{
"_id" : ObjectId("5203736b1a78238235b6ffc0"),
"images" : [
{
"id" : ObjectId("516bef7fc05e877b31000000"),
"primary" : true
},
{
"id" : ObjectId("516bef2ac05e879622010000"),
"primary" : true
},
{
"id" : ObjectId("516beeb7c05e879e2a000020"),
"primary" : true
}
],
"name" : "James",
"etc" : true
}
This outputs:
{
"result" : [
{
"_id" : ObjectId("5203736b1a78238235b6ffc0"),
"images" : [
{
"id" : ObjectId("516bef7fc05e877b31000000"),
"primary" : true
},
{
"id" : ObjectId("516bef2ac05e879622010000"),
"primary" : true
},
{
"id" : ObjectId("516beeb7c05e879e2a000020"),
"primary" : true
}
],
"name" : "James",
"etc" : true,
"same" : 1
},
{
"_id" : ObjectId("5203730bf8eaa52a846ebc3e"),
"images" : [
{
"id" : ObjectId("516bef7fc05e877b31000000"),
"primary" : true
},
{
"id" : ObjectId("516bef2ac05e879622010000"),
"primary" : true
},
{
"id" : ObjectId("516beeb7c05e879e2a000010"),
"primary" : true
}
],
"name" : "Derick",
"etc" : null,
"same" : 1
}
],
"ok" : 1
}

Wouldn't it be much simpler to exclude all documents where images has primary:true element?
{ "images" :
{ "$not" :
{"$elemMatch" : { "primary" : true }}
}
}
Naturally, this is only applicable to a boolean nested field, as in this case.

Having sort trouble with a similar kind of query...But just look at Dericks code, the docs say not to use $first within a $group operation, unless the $group operation is immediately after a $sort.
http://docs.mongodb.org/manual/reference/operator/aggregation/first/#grp._S_first

Presuming Images is a document you could use(from the shell):
db.images.find({'primary':'false'})
If Images is an object:
db.mydoc.find({'images':{'primary':'false'}})

Related

MongoDB not using Index - possible collation issue?

MongoDB not using Index - possible collation issue?
We have a MongoDB Query, fully indexed, that should be scanning at most 4/5 rows. However the query appears to use one only element of the index (the integer) and ignore the string portion.
We are using a case-insensitive collation (strength=2), but it makes no difference if we specify this or not. Documentation: https://docs.mongodb.com/manual/core/index-case-insensitive/
Do collations use indexes? Is there a more efficient way of do we manually need to de-normalise? NOTE: we're not actually using any non-standard characters, the collation is specified purely for case insensitivity.
Version (supports collation):
MongoDB server version: 3.6.13
db.version() => 3.6.13
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
gives:
{
"featureCompatibilityVersion" : {
"version" : "3.6"
},
"ok" : 1,
"operationTime" : Timestamp(1565754388, 51),
"$clusterTime" : {
"clusterTime" : Timestamp(1565754388, 51),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
DB Structure (summarised) is
{
"PrimaryID": (int)XXX,
"aTables": {
"userExt": [
{
"userExtPlatform": (int)XXX,
"userExtID": (string)XXX,
"userExtActive": (int 1 | 0)XXX,
},
{
"userExtPlatform": (int)XXX,
"userExtID": (string)XXX,
"userExtActive": (int 1 | 0)XXX,
},
...
],
"userOtherData": [
{
"otherDataField1": XXX,
"otherDataField2": XXX,
},
...
],
...
}
}
Index is set up as follows (note - collation is specified as {locale:en, strength: 2}:
{
"v" : 2,
"key" : {
"aTables.userExt.userExtPlatform" : 1,
"aTables.userExt.userExtID" : 1
},
"name" : "extPlatform",
"background" : false,
"ns" : "archive.users",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
}
}
The query (trying with/without specifying collation)
use archive;
db.users.find(
{
"aTables.userExt.userExtPlatform": 4,
"aTables.userExt.userExtID": "AStringValue",
"aTables.userExt.userExtActive": 1,
"deleted": { "$exists": false }
}
)
db.users.find(
{
"aTables.userExt.userExtPlatform": 4,
"aTables.userExt.userExtID": "AStringValue",
"aTables.userExt.userExtActive": 1,
"deleted": { "$exists": false }
}
).collation( { locale: "en", strength: 2 } )
Note: Removing the 'deleted' clause makes no difference to the speed / results / explain.
Here is the explain, and it shows a vast number of keys and documents queried.
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "archive.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"aTables.userExt.userExtActive" : {
"$eq" : 1
}
},
{
"aTables.userExt.userExtID" : {
"$eq" : "PrivateStringRemoved"
}
},
{
"aTables.userExt.userExtPlatform" : {
"$eq" : 4
}
},
{
"$nor" : [
{
"deleted" : {
"$exists" : true
}
}
]
}
]
},
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"aTables.userExt.userExtActive" : {
"$eq" : 1
}
},
{
"aTables.userExt.userExtID" : {
"$eq" : "PrivateStringRemoved"
}
},
{
"$nor" : [
{
"deleted" : {
"$exists" : true
}
}
]
}
]
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"aTables.userExt.userExtPlatform" : 1,
"aTables.userExt.userExtID" : 1
},
"indexName" : "extPlatform",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : true,
"multiKeyPaths" : {
"aTables.userExt.userExtPlatform" : [
"aTables.userExt"
],
"aTables.userExt.userExtID" : [
"aTables.userExt"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"aTables.userExt.userExtPlatform" : [
"[4.0, 4.0]"
],
"aTables.userExt.userExtID" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 1304,
"totalKeysExamined" : 290114,
"totalDocsExamined" : 290114,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"aTables.userExt.userExtActive" : {
"$eq" : 1
}
},
{
"aTables.userExt.userExtID" : {
"$eq" : "PrivateStringRemoved"
}
},
{
"$nor" : [
{
"deleted" : {
"$exists" : true
}
}
]
}
]
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 1245,
"works" : 290115,
"advanced" : 0,
"needTime" : 290114,
"needYield" : 0,
"saveState" : 2267,
"restoreState" : 2267,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 290114,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 290114,
"executionTimeMillisEstimate" : 270,
"works" : 290115,
"advanced" : 290114,
"needTime" : 0,
"needYield" : 0,
"saveState" : 2267,
"restoreState" : 2267,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"aTables.userExt.userExtPlatform" : 1,
"aTables.userExt.userExtID" : 1
},
"indexName" : "extPlatform",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : true,
"multiKeyPaths" : {
"aTables.userExt.userExtPlatform" : [
"aTables.userExt"
],
"aTables.userExt.userExtID" : [
"aTables.userExt"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"aTables.userExt.userExtPlatform" : [
"[4.0, 4.0]"
],
"aTables.userExt.userExtID" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 290114,
"seeks" : 1,
"dupsTested" : 290114,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "api-mdb-archive-03",
"port" : 27017,
"version" : "3.6.13",
"gitVersion" : "db3c76679b7a3d9b443a0e1b3e45ed02b88c539f"
},
"ok" : 1,
"operationTime" : Timestamp(1565753056, 9),
"$clusterTime" : {
"clusterTime" : Timestamp(1565753056, 9),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
The log output also confirms that it's checking a huge number of documents, and that collation comes through.
2019-08-14T03:23:53.912+0000 I COMMAND [conn20679] command archive.users appName: "MongoDB Shell" command: find { find: "users", filter: { aTables.userExt.userExtPlatform: 4.0, aTables.userExt.userExtID: "PrivateStringRemoved", aTables.userExt.userExtActive: 1.0, deleted: { $exists: false } }, collation: { locale: "en", strength: 2.0 }, lsid: { id: UUID("3178aa31-5ee9-4a79-9848-f01c1842f542") }, $clusterTime: { clusterTime: Timestamp(1565753015, 41), signature: { hash: BinData(0, 0000000000000000000000000000000000000000), keyId: 0 } }, $db: "archive" } planSummary: IXSCAN { aTables.userExt.userExtPlatform: 1, aTables.userExt.userExtID: 1 } keysExamined:289966 docsExamined:289966 cursorExhausted:1 numYields:2267 nreturned:0 reslen:228 locks:{ Global: { acquireCount: { r: 4536 } }, Database: { acquireCount: { r: 2268 } }, Collection: { acquireCount: { r: 2268 } } } protocol:op_msg 1546ms
2019-08-14T03:24:16.864+0000 I COMMAND [conn20679] command archive.users appName: "MongoDB Shell" command: explain { explain: { find: "users", filter: { aTables.userExt.userExtPlatform: 4.0, aTables.userExt.userExtID: "PrivateStringRemoved", aTables.userExt.userExtActive: 1.0, deleted: { $exists: false } }, collation: { locale: "en", strength: 2.0 } }, verbosity: "executionStats", lsid: { id: UUID("3178aa31-5ee9-4a79-9848-f01c1842f542") }, $clusterTime: { clusterTime: Timestamp(1565753033, 128), signature: { hash: BinData(0, 0000000000000000000000000000000000000000), keyId: 0 } }, $db: "archive" } numYields:2267 reslen:3578 locks:{ Global: { acquireCount: { r: 4536 } }, Database: { acquireCount: { r: 2268 } }, Collection: { acquireCount: { r: 2268 } } } protocol:op_msg 1341ms
For completeness, this is driven by PHP, but verified in Mongo CMD as above. Here is the PHP:
$aParams = [
'aTables.userExt.userExtID' => 4,
'aTables.userExt.userExtPlatform' => 'PrivateStringRemoved',
'aTables.userExt.userExtActive' => 1,
'deleted': [
'$exists' => false
]
];
$aOptions = [
'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::RP_NEAREST),
'skip' => $start,
'limit' => $limit,
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array'
],
'collation' => [
'locale' => 'en',
'strength' => 2
],
];
try {
$aResults = $collectionArchive->find($aParams, $aOptions);
} catch (\Exception $exception) {
throw new ArchiverException('Mongo Error', ArchiverRequest::ERROR_MONGO, $exception->getMessage());
}
Posting here, for reassurance if anyone searches. (Based on other answers)
Having played around, the following syntax is the correct one. You need to group the final elements into $elemMatch as below.
db.users.find(
{
"aTables.userExt" : {
"$elemMatch" : {
"userExtPlatform": 4,
"userExtID": "AStringValue",
"userExtActive": 1
}
}
}
).collation( { locale: "en", strength: 2 } ).explain("executionStats")
As requested: here is the explain:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "archive.users",
"indexFilterSet" : false,
"parsedQuery" : {
"aTables.userExt" : {
"$elemMatch" : {
"$and" : [
{
"userExtActive" : {
"$eq" : 1
}
},
{
"userExtID" : {
"$eq" : "AStringValue"
}
},
{
"userExtPlatform" : {
"$eq" : 4
}
}
]
}
}
},
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"aTables.userExt" : {
"$elemMatch" : {
"$and" : [
{
"userExtPlatform" : {
"$eq" : 4
}
},
{
"userExtID" : {
"$eq" : "AStringValue"
}
},
{
"userExtActive" : {
"$eq" : 1
}
}
]
}
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"aTables.userExt.userExtPlatform" : 1,
"aTables.userExt.userExtID" : 1
},
"indexName" : "extPlatform",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : true,
"multiKeyPaths" : {
"aTables.userExt.userExtPlatform" : [
"aTables.userExt"
],
"aTables.userExt.userExtID" : [
"aTables.userExt"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"aTables.userExt.userExtPlatform" : [
"[4.0, 4.0]"
],
"aTables.userExt.userExtID" : [
"[\")MOK9C5S)?Q1\u0001\u0010\", \")MOK9C5S)?Q1\u0001\u0010\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 4,
"totalKeysExamined" : 0,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"aTables.userExt" : {
"$elemMatch" : {
"$and" : [
{
"userExtPlatform" : {
"$eq" : 4
}
},
{
"userExtID" : {
"$eq" : "AStringValue"
}
},
{
"userExtActive" : {
"$eq" : 1
}
}
]
}
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"aTables.userExt.userExtPlatform" : 1,
"aTables.userExt.userExtID" : 1
},
"indexName" : "extPlatform",
"collation" : {
"locale" : "en",
"caseLevel" : false,
"caseFirst" : "off",
"strength" : 2,
"numericOrdering" : false,
"alternate" : "non-ignorable",
"maxVariable" : "punct",
"normalization" : false,
"backwards" : false,
"version" : "57.1"
},
"isMultiKey" : true,
"multiKeyPaths" : {
"aTables.userExt.userExtPlatform" : [
"aTables.userExt"
],
"aTables.userExt.userExtID" : [
"aTables.userExt"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"aTables.userExt.userExtPlatform" : [
"[4.0, 4.0]"
],
"aTables.userExt.userExtID" : [
"[\")MOK9C5S)?Q1\u0001\u0010\", \")MOK9C5S)?Q1\u0001\u0010\"]"
]
},
"keysExamined" : 0,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "api-mdb-archive-03",
"port" : 27017,
"version" : "3.6.13",
"gitVersion" : "db3c76679b7a3d9b443a0e1b3e45ed02b88c539f"
},
"ok" : 1,
"operationTime" : Timestamp(1565870195, 8),
"$clusterTime" : {
"clusterTime" : Timestamp(1565870195, 8),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}

FOSElastica nested query

My collections are like this:
{
"_index" : "test_index",
"_type" : "test_type",
"_id" : "10000",
"_score" : 1.0,
"_source" : {
"user_id" : 12,
"index_date" : {
"date" : "2018-02-06 14:25:49.816952",
"timezone_type" : 3,
"timezone" : "UTC"
},
"rating" : null,
"orders" : [
{
"hour" : "08",
"count" : 1
},
{
"hour" : "10",
"count" : 1
}
],
"products" : [
{
"p_id" : 970111,
"count" : 4
},
{
"p_id" : 1280811,
"count" : 1
},
]
}
},
and tried to access to {"hour":"10"}
My query is:
$query = new Query\Nested();
$query->setPath('orders');
$term = new Term();
$term->setTerm('orders.hour', $order->getCreatedAt()->format('H'));
$query->setQuery($term);
dump($finder->find($query));die;
but i got the following error:
[Elastica\Exception\ResponseException]
failed to create query: {
"nested" : {
"query" : {
"term" : {
"orders.hour" : {
"value" : "12",
"boost" : 1.0
}
}
},
"path" : "orders",
"ignore_unmapped" : false,
"score_mode" : "avg",
"boost" : 1.0
}
} [index: test_index] [reason: all shards failed]
Your documents not look like nested queries.
I assume that finder is your repository manager that is defined as orders repository, your code should look something like this
$finder = $this->get('fos_elastica.repository_manager')->getRepository('YourBundle:order');
$boolquery = new Query\BoolQuery();
$term = new Query\Term();
$term->setTerm('hour', $order->getCreatedAt()->format('H'));
$boolquery->addMust($term);
$finder->find($boolquery);

Mongo Db aggregate $lookup returns empty array

when trying to "JOIN" operation with $lookup but results count is ok but "as" document is empty
I have two collections and i need to get user details from subscribercol with user_id in employer_jobscol
subscribercol
{
"_id" : ObjectId("58187e7551d244640626d7e1"),
"type" : "job_seeker",
"firstname" : "vishnu",
"lastname" : "kumar pv",
"email_array" : {
"primary" : "test#test.com",
"secondary" : "test#test.test",
"verified" : false
},
"address_array" : {
"address" : "test address22d",
"streetname" : "test222d",
"pincode" : "test222d",
"city" : "dddd",
"state" : "ALASKA2d",
"country" : "Argentinad"
},
"phone_array" : {
"primary" : "",
"secondary" : "",
"verified" : ""
},
"languages" : [
"english",
"malayalam",
"english2"
]
}
employer_jobscol
{
"_id" : ObjectId("582ada6b51d244073e2a7541"),
"employer_id" : ObjectId("58187e7551d244640626d7e1"),
"job_id" : "testjob16946",
"job_title" : "Test Job 25",
"category" : "IT",
"vacancies" : "5",
"salary" : "200000",
"location" : "Kollam",
"employer_name" : "test test",
"mobile" : "9123456987",
"video" : "",
"image" : "",
"work_place" : "option1",
"email" : "test#test.test",
"skills" : [
"php"
],
"isActive" : true,
"applied_users" : [
{
"user_id" : ObjectId("581b364751d2445c311cf6f1"),
"accepted" : false
},
{
"user_id" : ObjectId("58187e7551d244640626d7e1"),
"accepted" : false
}
]
}
my database query here, (executed with Robomongo )
db.getCollection('employer_jobscol').aggregate([ {
$unwind: "$applied_users"
},
{
$lookup:
{
from: "subscribercol",
localField: "user_id",
foreignField: "_id",
as: "subscribercol_docs"
}
}
])
Result is
{
"_id" : ObjectId("582ada6b51d244073e2a7541"),
"employer_id" : ObjectId("58187e7551d244640626d7e1"),
"job_id" : "testjob16946",
"job_title" : "Test Job 25",
"category" : "IT",
"vacancies" : "5",
"salary" : "200000",
"location" : "Kollam",
"employer_name" : "test test",
"mobile" : "9123456987",
"video" : "",
"image" : "",
"work_place" : "option1",
"email" : "test#test.test",
"skills" : [
"php"
],
"isActive" : true,
"applied_users" : {
"user_id" : ObjectId("58187e7551d244640626d7e1"),
"accepted" : false
},
"subscribercol_docs" : []
}
here subscribercol_docs is empty array i need user info (name, address etc..),
Because there is no user_id field in local document its "applied_users.user_id"
Try this
db.getCollection('employer_jobscol').aggregate([ {
$unwind: "$applied_users"
},
{
$lookup:
{
from: "subscribercol",
localField: "applied_users.user_id", // <-- check here
foreignField: "_id",
as: "subscribercol_docs"
}
}
])

How to combine a filter with distance for a search using Elasticsearch?

I have a elasticsearch question:
Here is my mapping below:
{
"9849asdasprofiles" : {
"mappings" : {
"profile" : {
"properties" : {
"activity" : {
"type" : "long"
},
"address" : {
"type" : "string"
},
"cPerson" : {
"type" : "string"
},
"category_id" : {
"type" : "long"
},
"city" : {
"type" : "string"
},
"country" : {
"type" : "string"
},
"created_at" : {
"properties" : {
"date" : {
"type" : "string"
},
"timezone" : {
"type" : "string"
},
"timezone_type" : {
"type" : "long"
}
}
},
"editors" : {
"properties" : {
"__cloner__" : {
"type" : "object"
},
"__initializer__" : {
"type" : "object"
},
"__isInitialized__" : {
"type" : "boolean"
}
}
},
"fax" : {
"type" : "string"
},
"foto_url" : {
"type" : "string"
},
"has_siegel" : {
"type" : "long"
},
"has_upgrade" : {
"type" : "long"
},
"hsnr" : {
"type" : "string"
},
"id" : {
"type" : "long"
},
"info_text" : {
"type" : "string"
},
"location" : {
"type" : "geo_point",
"fielddata" : {
"format" : "compressed",
"precision" : "3m"
}
},
"logo_url" : {
"type" : "string"
},
"name" : {
"type" : "string"
},
"phone" : {
"type" : "string"
},
"published" : {
"type" : "boolean"
},
"role_limit_article" : {
"type" : "boolean"
},
"role_limit_clicktracking" : {
"type" : "boolean"
},
"role_limit_contact_fax" : {
"type" : "boolean"
},
"role_limit_contact_mail" : {
"type" : "boolean"
},
"role_limit_contact_phone" : {
"type" : "boolean"
},
"role_limit_contact_website" : {
"type" : "boolean"
},
"role_limit_create_profile" : {
"type" : "boolean"
},
"role_limit_events" : {
"type" : "boolean"
},
"role_limit_following" : {
"type" : "boolean"
},
"role_limit_gallery" : {
"type" : "boolean"
},
"role_limit_images" : {
"type" : "boolean"
},
"role_limit_info_fields" : {
"type" : "boolean"
},
"role_limit_logo" : {
"type" : "boolean"
},
"role_limit_messages" : {
"type" : "boolean"
},
"role_limit_products" : {
"type" : "boolean"
},
"role_limit_view_follower" : {
"type" : "boolean"
},
"role_limit_visitors" : {
"type" : "boolean"
},
"role_limit_visittracking" : {
"type" : "boolean"
},
"siegel_url" : {
"type" : "string"
},
"slug" : {
"type" : "string"
},
"street" : {
"type" : "string"
},
"upgrade_level" : {
"type" : "long"
},
"upgrade_sort" : {
"type" : "integer"
},
"visible" : {
"type" : "boolean"
},
"website" : {
"type" : "string"
},
"zipcode" : {
"type" : "string"
}
}
}
}
}
}
For db-entries in the mapping above I want to get only the entries with defined IDs. The IDs are in an array. After filtering These items, then I want to run a distance search. So I ran this query below:
{
"index": "9849asdasprofiles",
"type": "profile",
"size": 30,
"from": 0,
"body": {
"query": {
"function_score": {
"functions": [
{
"linear": {
"location": {
"origin": "48.136833417046,11.570900696682",
"offset": "2km",
"scale": "1km"
}
}
}
],
"score_mode": "avg",
"boost_mode": "replace",
"query": {
"bool": {
"must": [
{
"term": {
"published": "1"
}
},
{
"match": {
"country": "DE"
}
}
],
"filter": {
"terms": {
"id": [
5336,
4955,
5488
]
}
}
}
}
}
},
"aggs": {
"rings": {
"geo_distance": {
"field": "location",
"origin": "48.136833417046,11.570900696682",
"distance_type": "arc",
"unit": "km",
"ranges": [
{
"to": 25
}
]
}
}
},
"script_fields": {
"distance": {
"lang": "groovy",
"params": {
"lat": 48.136833417046,
"lon": 11.570900696682
},
"script": "doc['location'].arcDistanceInKm(lat,lon)"
}
},
"sort": [
{
"upgrade_sort": {
"order": "desc"
}
},
{
"has_siegel": {
"order": "desc"
}
},
{
"_geo_distance": {
"location": {
"lat": 48.136833417046,
"lon": 11.570900696682
},
"order": "asc",
"unit": "km"
}
}
]
},
"fields": [
"_source",
"distance"
]
}
The problem is: The result contains entries with the specified IDs, but the distance filter doesn't affect the results.
Any Ideas as to how to do this?
Ok, I got it: The solution was really simple. I only had to change the filter part (in PHP) from
$params['body']['query']['function_score']['query']['bool']['filter']
to
$params['body']['query']['function_score']['filter']
But I couldn't find that part in the elastisearch documentation... :(

How i can convert a mongo query to laravel 5.1?

I have one collection in mongodb and my document is :
"_id" : ObjectId("55caf368b649fe6d068b4568"),
"title" : "lrgwkwjg",
"comments" : [
{
"id" : NumberLong(793644433634148),
"name" : "werkwehgbwejhf",
"title" : "jrg nejrngjern gjer",
"created_at" : {
"date" : "2015-08-15 11:01:54",
"timezone_type" : NumberLong(3),
"timezone" : "UTC"
},
"comment" : "nrjfnwejf wjkenf kjwef",
"user_id" : ObjectId("5599009fb649fe72188b4567"),
"approve" : false,
"url" : "http://takhfif.dev/api/v1/comment/793644433634148"
},
{
"id" : NumberLong(966385963890287),
"name" : "werkwehgbwejhf",
"title" : "jrg nejrngjern gjer",
"created_at" : {
"date" : "2015-08-15 11:09:17",
"timezone_type" : NumberLong(3),
"timezone" : "UTC"
},
"comment" : "nrjfnwejf wjkenf kjwef",
"user_id" : ObjectId("5599009fb649fe72188b4567"),
"approve" : false,
"url" : "http://takhfif.dev/api/v1/comment/966385963890287"
}
],
I want to update comments as record id = 966385963890287, and the approve field must be convert to true - in conclude, i use this query as below:
public function approveComment($id,Product $comment)
{
$comment->update([
'comments.id'=>$id
]
,
[
'$set'=>[
'comments.$.approve'=>true
]
]
);
}
But if i use that query i got an error as below :
MongoWriteConcernException in Collection.php line 42:
localhost:27017: cannot use the part (comments of comments.id) to traverse the element ({comments: [ { id: 793644433634148, name: "werkwehgbwejhf", title: "jrg nejrngjern gjer", created_at: { date: "2015-08-15 11:01:54", timezone_type: 3, timezone: "UTC" }, comment: "nrjfnwejf wjkenf kjwef", user_id: ObjectId('5599009fb649fe72188b4567'), approve: true, url: "http://takhfif.dev/api/v1/comment/793644433634148" }, { id: 966385963890287, name: "werkwehgbwejhf", title: "jrg nejrngjern gjer", created_at: { date: "2015-08-15 11:09:17", timezone_type: 3, timezone: "UTC" }, comment: "nrjfnwejf wjkenf kjwef", user_id: ObjectId('5599009fb649fe72188b4567'), approve: false, url: "http://takhfif.dev/api/v1/comment/966385963890287" } ]})
How can i fix that?
Hint : i use jenssegers/laravel-mongodb package in laravel5.1

Categories