I am trying to match "new york" in a search (not places containing "new" or "york" separately)
here is my current query:
"query" : {
"query_string" : {
"query" : "new york" ,
"fields" : ["city"]
}
},
"filter" : {
"and" : [{
"query" : {
"query_string" : {
"query" : "country:US"
}
}
}]
}
However this keeps returning places named "york" rather than "new york"
I am not fully understanding how this works and would appreciate some help in getting this to actually work for me.
If you want both words to appear in the same document you need to change the default operator like this:
"query" : {
"query_string" : {
"query" : "new york" ,
"fields" : ["city"],
"default_operator" : "AND"
}
}
or specify it ion the query:
"query" : {
"query_string" : {
"query" : "new AND york" ,
"fields" : ["city"]
}
}
Have a look at the query string documentation.
Otherwise, if you want both words to appear close to each other in the same document you need to make a phrase query like this:
"query" : {
"match_phrase" : {
"message" : "new york"
}
}
By default the city field in "analyzed" by Elasticsearch which does the default tokenization of words.
New York => *New*, *York*
In order to keep the tokens intact (mostly used for aggregation), you need to explicitly make the city field "not analyzed" using multi field
'city' => [
'type' => 'string',
'fields' => [
'raw' => [
'type' => 'string',
'index' => 'not_analyzed'
]
]
]
Now you can use city.raw to get non analyzed values.
Related
This is the structure for my MongoDB documents
{
"_id" : ObjectId("5aa02da4f6c9bf20da58017b"),
"Name" : "HP Envy",
"Model" : "m6 convertible x360",
"Cost" : 1350,
"Description" : "Sleek and slim laptop designed perfectly for business p
urposes",
"Keywords" : [
"Touchscreen",
"Rotation",
"x360",
"Slim",
"HP"
],
"Reviews" : [
{
"User" : "User 1",
"Comment" : "Great Laptop",
"Rating" : 4.5
},
{
"User" : "User 2",
"Comment" : "Great Laptop",
"Rating" : 4.5
}
]
}
I want to access the data contained inside "Reviews" using php. I can access it normal using
$coll=$db->Product;
$cursor = $coll->find();
and then echo using a foreach to display in a tabular format. But i only know how to access the ID, name etc. How can i access the Reviews inside the object arrays? i tried something like this:
$test=$coll->find(array( 'Reviews.User' => 'User 1' ));
when i try to echo it it gives me an error: Catchable fatal error: Object of class MongoCursor could not be converted to string
I'm lost please help.. I apologize if i repeated the question but i couldn't find it anywhere else
I'm having issues with the new mongodb driver for php.
While iterator_to_array works ok for ->find, if I only return one document it has MongoDB\Model\BSONDocument format.
$result = $db->clients->findOne(array('_id' => $id));
$result = (array) $result;
In Mongo the document looks something like:
{
"_id" : ObjectId("3894713i4b13iu412"),
"active" : true,
"logo" : "this is logo",
"settings" : {
"email" : "days",
"testMode" : false
},
"stats" : {
"f" : {
"all" : [
{
"count" : NumberLong(15846),
"sum" : NumberLong(149479)
},
{
"count" : NumberLong(15846),
"sum" : NumberLong(148891)
},
{
"count" : NumberLong(15846),
"sum" : {
"1" : NumberLong(15522),
"2" : NumberLong(324)
}
}
]
},
"l" : {
"order" : ISODate("2016-12-05T09:10:53.855+0000"),
"feedback" : ISODate("2016-12-05T08:34:48.403+0000")
}
},
"title" : "hhh.ro",
"url" : "sdfasdf"
}
This will only turn first level elements into an array, but nested document elements still remain MongoDB\Model\BSONDocument;
iterator_to_array doesn't work because this is not something iterable.
How do I convert entire document to an associative array like the old mongo driver or a stdClass?
you can set how the data is returned globally in database->setCollection options, Set typeMap to array
'typeMap' =>[
'document' => 'array',
'root' => 'array'
]
Link to Doc
I couldn't find the setCollection suggested by #Delcon in PHP MongoDB library so I used the below method.
typeMap option can also be set in the options array inside findOne.
$someCollection->findOne(
[],
['typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']]
);
Link to Doc
edit:
You could also pass the options array to the connector to set it globally as described by this Stackoverflow post.
$options = ["typeMap" => ['root' => 'array', 'document' => 'array']];
$conn = new MongoDB\Client("mongodb://localhost:27017", [], $options);
i actually have a issue with mongodb im trying to update/add a value in a nested array.
{
"_id" : ObjectId("56c37e98aff662100900002a"),
"name" : "michell",
"game" : [{
"name" : "GTA",
"badges" : [{
"name" : "pacifist"
}, {
"name" : "killemall"
}]
}]
}
you can find below the way i tried but actually it just rewrite the badges array of create new game array
$collection->update(array('_id' =>new MongoId($id),'jeux.name'=>$name), array('$set' => array('jeux'=>array('name' => $name,'badges'=>array('name'=>$badge)))));
i can't find the issue here if you could help me
Well i found a solution i don't know if its the best one but it seems like it work
$collection->update(array('_id' =>new MongoId($id),'jeux.name'=>$name), array('$push' => array('jeux.$.badges'=>array('name'=>$badge))));
im using the $ in jeux.$.badges
I am trying to update() a specific single array in a collection, but while it works fine with $push parameter on a single, specific array, it does not work with a $set parameter.
I don't quite understand logic behind that, because when I use such an example of $pushing the element:
$post_comment = array('$push' =>
array("comments" => array(
"_id" => new MongoId(),
"comment" => htmlspecialchars($_POST['comment']),
"author" => $user->username,
"date" => new MongoDate()
)
)
);
$entries->update(array(
"_id" => $_GET["id"]), $post_comment);
It gives me an array in a MongoDB database which looks more or less like this (with four items pushed in, respectively) :
{
"_id" : "css-clearfix-explained",
"comments" : [
{
"_id" : ObjectId("540cc940af105b19133c9869"),
"comment" : "aaa",
"author" : "maciejsitko",
"date" : ISODate("2014-09-07T21:08:16.215Z")
},
{
"_id" : ObjectId("540cc943af105b19133c986a"),
"comment" : "bbb",
"author" : "maciejsitko",
"date" : ISODate("2014-09-07T21:08:19.542Z")
},
{
"_id" : ObjectId("540cc946af105b19133c986b"),
"comment" : "ccc",
"author" : "maciejsitko",
"date" : ISODate("2014-09-07T21:08:22.968Z")
}
]
}
Which is basically what I want to have, and logically, works fine according to the documentation. But when I try the same with $set as for to edit an individual comment, in the similar fashion as shown:
$edit_comment = array('$set' =>
array("comments" => array(
"_id" => new MongoId($_POST['cmt-id']),
"comment" => htmlspecialchars($_POST['edit-comment']),
"author" => $user->username,
"date" => new MongoDate()
)
)
);
$entries->update(array(
"_id" => $_GET["id"]), $edit_comment);
It outputs four different arrays in place of the previous arrays, to illustrate that, i'll show what happened when I updated first comment "aaa" to "ddd" :
{
"_id" : "css-clearfix-explained",
"comments" : {
"_id" : ObjectId("540cc940af105b19133c9869"),
"comment" : "ddd\r\n ",
"author" : "maciejsitko",
"date" : ISODate("2014-09-07T21:12:10.833Z")
}
}
All the four array elements were pretty much erased and in their place appeared four fields as four independent array elements.
How come? Shouldn't it just work just fine like the example with $push above?
You didn't specify an index within comments. Therefore, $set replaced the array comments with the associated array supplied.
If you want to update a comment, then change your query in the first argument to match a comment by a unique field. Ex, date. In the second argument use a positional $ operator.
Example:
$edit_comment = array('$set' =>
array("comments.$" => array(
"_id" => new MongoId($_POST['cmt-id']),
"comment" => htmlspecialchars($_POST['edit-comment']),
"author" => $user->username,
"date" => new MongoDate()
)
)
);
// this assumes the post date is unique. On second though use something else.
$query = array( "_id" => $_GET["id"], "comments.date" => $_POST['post-date'])
$entries->update( $query, $edit_comment);
Check this out for more info and better explanation:
MongoDB - $set to update or push Array element
I have this document in the 'families' table:
{
"_id" : {
"$oid" : "51b701a81c1d7bd459000001"
},
"items" : {
"tasks" : [{
"due_date" : "07/06/13",
"assignees" : "Dorel#yahoo.com",
"_id" : {
"$oid" : "51ba0c181c1d7b7c0e00000c"
},
"type" : "task",
"author" : "cornel#gmail.com",
"creation_date" : "13/06/2013",
"name" : "Task0"
}
]
}
}
Using Codeigniter's ActiveRecord Library I'm trying to access an element in the 'tasks' array by doing so ( '$item_id' is the id of the task I'm looking for):
$this->mongo_db->where(array('_id' => $this->session->userdata('family_id')))
->where(array('items.$.$._id' => $item_id));
$query = $this->mongo_db->get('families');
So I tried to use the dot notation and the positional operator. But all I get is an empty array.
Please, help, anyone?