PHP MongoDb, find all referenced documents when collection is indexed array - php

I have the following structure in mongo
{
"_id": ObjectId("5188deba4c2c989909000000"),
"_type": {
"0": "Model_Discs"
}
},
"title": "really cool cd",
"referencedBy": {
"0": {
"$ref": "discs",
"$id": ObjectId("4e171cade3a9f23359e98552")
},
"1": {
"$ref": "discs",
"$id": ObjectId("5045c3222b0a82ec46000000")
}
}
}
This is actually an indexed array that holds references to other documents. I to find all the documents that have a reference to ObjectId("5045c3222b0a82ec46000000").
At first I wrote "referencedBy.1.$id": ObjectId("5045c3222b0a82ec46000000") which doesn't work (as expected) because the ObjectId can be found under different index in other documents
i.e.
referencedBy.1.$id
referencedBy.5.$id
referencedBy.3.$id
So I need to find all documents that reference my ObjectId who are anywhere under the referencedBy DocumentSet. Something like
"referencedBy.*.$id": ObjectId("5045c3222b0a82ec46000000")

I don't quite see why you have such a complicated structure. Particularily the "0" and "1" keys are problematic, especially dealing with PHP as it doesn't really like arrays with numerical string keys. The $ref/$id fields come from MongoDBRef, which should avoid as they don't provide you with any functionality.
You should just have:
{
"_id": ObjectId("5188deba4c2c989909000000"),
"_type": "Model_Discs",
"title": "really cool cd",
"referencedBy": [
ObjectId("4e171cade3a9f23359e98552"),
ObjectId("5045c3222b0a82ec46000000")
]
}
Then you can simply query with:
db.collection.find( { referencedBy: new ObjectId("5045c3222b0a82ec46000000") } );

Related

I want a more consolidate json format

I am getting json array after getting applying query logic.
[
{
"id": "3",
"diag_name": "LT Diagnostics",
"test_name": "Alk PO4",
"booking_date": "2018-05-20"
},
{
"id": "3",
"diag_name": "LT Diagnostics",
"test_name": "CRP",
"booking_date": "2018-05-20"
},
{
"id": "4",
"diag_name": "Seepz Diagnostics",
"test_name": "Alk PO4",
"booking_date": "2018-05-21"
}
]
But i want a more justified json array written below.
[
{
"diag_name": "LT Diagnostics",
"test_name": [
{
"id": "3",
"name" : "Alk PO4"
},
{
"id": "3",
"name" : "CRP"
}
],
"booking_date": "2018-05-20"
},
{
"diag_name": "Seepz Diagnostics",
"test_name": [
{
"id": "4",
"name" : "Alk PO4"
}
],
"booking_date": "2018-05-21"
},
]
I am not getting it,How to do in php. I want a more consolidate json format.
Have you tried changing your SQL query to group by diag_name and booking_date? That would be the first step I’d employ to get the outer data.
Formatting the data in the nested manner you’re after could be a function of whatever record serializer you’re using — does it support nested JSON as a return type, or only flat JSON as your example return value shows?
If the record set -> JSON serializer only ever returns flat data, the comments above are correct that you will have to write your own formatter to change the shape of the JSON yourself...
The accepted answer of this other question may be of help:
Create multi-level JSON with PHP and MySQL
I'm not a PHP guy but this is a typical scenario to use functional programming by means of the monad Map.
Looking online I've found this article that could help you.
Changing datasource output is not always (seldom indeed) a viable option.
Enjoy coding

Elasticsearch: What's the best way to search for a word within a string AND get score?

I'm using ElasticSearch's PHP client and I find really difficult to return results with scores whenever I want to search for a word that is "hidden" within a string.
This is an example:
I want to get all the documents where the field "file" has the word "anses" and files are named like this:
axx14anses19122015.zip
What I know about it
I know I should tokenize those words, can't realize how to do it.
Also I've read about aggregations but I'm really new to ES and I have to deliver a working piece ASAP.
What I've tried so far
REGEXP: using regular expressions is very expensive and does not return any scores, which is a must-to-have in order to shrink results and bring the user accurate information.
Wildcards: same thing, slow and no scores
Own script where I have a dictionary and search for critical words using regexp, if match, create a new field within that matched document with the word. The reason is to create a TOKEN so in future searches I can use regular match with scores. Negative side: the dictionary thing was totally denied by my boss so I'm here asking for any ideas.
Thanks in advance.
I suggest in your case nGram tokenizer see the example
I will create a analyzer and a mapping for a doc type
PUT /test_index
{
"settings": {
"number_of_shards": 1,
"analysis": {
"tokenizer": {
"ngram_tokenizer": {
"type": "nGram",
"min_gram": 4,
"max_gram": 4,
"token_chars": [ "letter", "digit" ]
}
},
"analyzer": {
"ngram_tokenizer_analyzer": {
"type": "custom",
"tokenizer": "ngram_tokenizer",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"doc": {
"properties": {
"text_field": {
"type": "string",
"term_vector": "yes",
"analyzer": "ngram_tokenizer_analyzer"
}
}
}
}
}
after that I`ll insert a document using your file name
PUT /test_index/doc/1
{
"text_field": "axx14anses19122015"
}
now I`ll just will use a query match
POST /test_index/_search
{
"query": {
"match": {
"text_field": "anses"
}
}
}
and will receive a reponse like this
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.10848885,
"hits": [
{
"_index": "test_index",
"_type": "doc",
"_id": "1",
"_score": 0.10848885,
"_source": {
"text_field": "axx14anses19122015"
}
}
]
}
}
What i did?
i just created a nGram tokenizer that will explode our string in 4 characters terms and will index this terms separated and they will be searched when I search a part of the string.
To see more, read this article https://qbox.io/blog/an-introduction-to-ngrams-in-elasticsearch
Hope it help!
Ok after trying -so- many times it worked. I'll share the solution just in case someone else needs it. Thank you so much to Waldemar, it was a really good approach and I still cannot see why it's not working.
curl -XPUT 'http://ipaddresshere/tokentest' -d
'{ "settings":
{ "number_of_shards": 1, "analysis" :
{ "analyzer" : { "myngram" : { "tokenizer" : "mytokenizer" } },
"tokenizer" : { "mytokenizer" : {
"type" : "nGram",
"min_gram" : "3",
"max_gram" : "5",
"token_chars" : [ "letter", "digit" ] } } } },
"mappings":
{ "doc" :
{ "properties" :
{ "field" : {
"type" : "string",
"term_vector" : "yes",
"analyzer" : "myngram" } } } } }'
Sorry for bad indentation, I'm really hurry but want to post the solution.
So, this will take any string from "field" and split it into nGrams with lenght 3 to 5. For example: "abcanses14f.zip" will result in:
abc, abca, abcan, bca, bcan, bcans, etc... until it reaches anses or a similar term which is matcheable and has a score related to it.

find() query MongoDB for php

Hi i am using mongoDb for my new project. I am trying to find values from mongodb database.
My mongoDB database collection name is: test and json format is below
{
"College": [
{
"name": "tamy",
"roll_no": "1"
},
{
"name": "abhi",
"roll_no": "2"
},
{
"name": "jack",
"roll_no": "3"
}
],
"School": [
{
"name": "zack",
"roll_no": "1"
},
{
"name": "mac",
"roll_no": "2"
},
{
"name": "john",
"roll_no": "3"
}
]
}
**And i want to find the name:abhi from test collection **
and my mongodb find query in php
$criteria = array(
'College'=> array(
'name'=> 'abhi'
));
$cursor = $collection->find($criteria);
but its not returning any value.
if i am displaying in php by using print_r.
print_r(iterator_to_array($cursor));
displaying empty array()
I need output like this:
name : jack
roll_no : 3
plz help me..
The key "College" is an array, your trying to treat it as a "subdocument" (but that wouldnt allow for multiple colleges to be stored)
You want the elemMatch keyword here I believe: http://docs.mongodb.org/manual/reference/operator/query/elemMatch/
EDIT: After looking at this again, I think you have your structure a little out of whack. How many "students" will there be per college or school? Keep in mind each parent document can not exceed 10mb, and when you select a document, the entire document must be sent back across the connection (unless you are using aggregate or map/reduce. I would think you may want to have a collection of Persons and then a key associating a person to... something else.

Using AND on same key in mongodb

I have a key in my document whose structure is as follow:
"tag": [
{
"schemeName": "http:\/\/somesite.com\/categoryscheme2",
"name": "Test Tag2",
"value": 1,
"slug": "test_tag2"
},
{
"schemaName": "http:\/\/somesite.com\/categoryscheme3",
"name": "Test Tag3",
"value": 1,
"slug": "test_tag3"
}
]
Now, I get inputs as tag=test_tag2ANDtest_tag3. How can I write a query for this?
I tried to iterate through the loop but I didnt got any results.
Correct me if I am wrong but you don't need an $and or $elemMatch, instead:
$mongodb->collection->find(array('tags.slug'=>array(
'$in' => array('test_tag2','test_tag3'))))
Should work, however, if your English suggests what a second read does, then you can also use $all in place of $in. This will ensure that all root documents must have those slugs in them.
use $elemMatch operator to match elements inside the array.

PHP - regex to reformat JSON

I've been trying to figure out how to reformat multiple JSON files into a single one using php, but am having a difficult time understanding how to use complex regular expressions. Suppose I hade multiple instances of the following JSON data:
{
"felines": {
"cats": [
{
"age": 7,
"name": "frank"
},
{
"age": 4,
"name": "popeye"
}
]
},
"canines": {
"dogs": [
{
"age": 2,
"name": "lucy"
},
{
"age": 12,
"name": "wilson"
}
]
}
}
Lets say I had 2 instances of this JSON object in a php script, and wanted to create a single JSON object that combined both "feline" objects from the two separate JSON instances I had, removing the "canines" objects. The file I'd ultimately want would look like this:
{
"felines": {
"cats": [
{
"age": 7,
"name": "frank"
},
{
"age": 4,
"name": "popeye"
}
]
},
"felines": {
"cats": [
{
"age": 6,
"name": "sam"
},
{
"age": 4,
"name": "kelly"
}
]
}
}
Does anyone know how i might be able splice and combine these JSON objects with regular expressions using php?
Thanks.
why don't you use json_encode & json_decode to do the works on php arrays seems to be a lot more easy then doing that with regular expressions.
I doubt this is a problem you should try to solve with regexes. Consider converting the JSON files to associative arrays, do your merging, and then change back to JSON.
Regular expressions are, in general, really bad at dealing with arbitrarily nested contexts like JSON data, HTML tags, programming languages, etc. Some extended regular expression libraries patch around those deficiencies.
But, really, is there a reason you need to do this in JSON itself? And with regex? You're probably going to have a much easier time deserializing the data to real PHP data structures, and merging/manipulating things there. Then, when you're done, re-serialize the result.
The best way to do it would be as RageZ suggested, using json_encode and json_decode, however JSON doesn't allow you to have the same key name, does it? The best you can get would be this:
{
"felines": {
"cats": [
{
"age": 7,
"name": "frank"
},
{
"age": 4,
"name": "popeye"
},
{
"age": 6,
"name": "sam"
},
{
"age": 4,
"name": "kelly"
}
]
}
}

Categories