MongoDB regex query with property that can be null - regex

Writing a MongoDB regex query in Spring with a field that can be null.
I want to query documents by name and phone:
Query(value = "{ {'name' : {$regex:?0,$options:'i'}},
{'phone' : {$regex:?1,$options:'i'}} }")
Document findByFullNameOrPhone(String fullName, String phone);
The value I'm passing through the query for phone is ".*" in an attempt to match everything.
It works but the problem is phone is a field that can be null. If the document has no phone value it's not included in the query result. Is it possible to use this query to find all documents in the database, even if the document does not have a value for phone?

Just add null check.
Query(value = "{
'name': {'$regex': ?0,'options': 'i'},
$or: [
{'phone': null},
{'phone': {'$regex': ?1,'options': 'i'}}
]
}")
Document findByFullNameOrPhone(String fullName, String phone);
Demo

Related

MongoDB $regex query to number fails

I stored info like this format on my MongoDB
{
name: 'Eric',
account: 13310
},
{
name: 'Ivan',
account: 12120
}
this is my noSQL sentence
db.users.find( "account": { $regex: /13/, $options: 'i' } );
But I got an error
Error: error: {
"ok" : 0,
"errmsg" : "$regex has to be a string",
"code" : 2,
"codeName" : "BadValue"
}
How could I make the query, I want to find whatever contains "13" on account index. I read about parse account index to String, but, the collection has over 100K documents, this is not the way.
I´m looking for this SQL Sentence
SELECT * FROM USERS WHERE ACCOUNT LIKE '%13%'
As you've seen, $regex only works with string fields; so because account is a numeric field, your query fails. Starting with MongoDB 4.0, you can use an aggregate pipeline to dynamically add a $toString version of account that you query against using a regex:
db.users.aggregate([
{$addFields: {accountStr: {$toString: '$account'}}},
{$match: {accountStr: /13/}}
])
The alternative would be to store a string copy of the account field in your documents that you could directly use.
I had a same problem, but i found a solution
Use like this:
"account": "/[A-z]*13/i"
Try this bro..
db.users.find( "account": { $regex: new RegExp( '^13' ), $options: 'i' } );

Elastic search Query String in Rails 4

I am using Elasticsearch in my application to search for a matching word anywhere in a table.
This is the query string i have used to fetch my result:
search({ query: { prefix: { _all: keywords }}, sort: [ { start_date: 'asc', start_time: 'asc' } ] })
The selected records were then being queried with the dates to match the date range(s) specified in the application, by the following query:
where("status_id= ? and active=? and (((start_date >= ?) and (start_date <= ?))
or ((start_date <= ?) and (? <= end_date)))",2,true,range_start_date,
range_end_date,range_start_date,range_start_date)
But i know this is not a good way to fetch results. Now i want to modify this to fetch just the required data from elasticsearch index.
After a long search i found "query_string" and "simple_query_string" to match my requirement. But i am unsuccessful till now to get the required result.
How can i append the query with the elasticsearch result to get the required records?
Can someone please help?
Thanks in advance.
Finally, i was able to find the answer for the question myself. I was able to filter the searched content according to date with a "filter" keyword.
I modified the query as:
search_query = {
query: {
prefix: {
_all: keywords
}
},
filter: {
query: {
query_string: {
query: "status_id:2 AND active:true AND
((start_date:>=#{range_start_date} AND start_date:<=#{range_end_date}) (start_date:<=#{range_start_date} AND end_date:>=#{range_start_date}))"
}
}
},
sort: [ { start_date: 'asc', start_time: 'asc' } ] }
And finally fetched the result by:
#result = self.search(search_query)
If there is anyway i could modify this code, please suggest. Thank You.

Execute Multiple Queries into single call onto Freebase

I want to get the results of multiple queries into single call onto freebase,which is there in this chapter http://mql.freebaseapps.com/ch04.html. I am using python for querying. I want to query like this
{ # Start the outer envelope
"q1": { # Query envelope for query named q1
"query":{First MQL query here} # Query property of query envelope
}, # End of first query envelope
"q2": { # Start query envelope for query q2
"query":[{Second MQL query here}] # Query property of q2
} # End of second query envelope
}
and get answers like
{
"q1": {
"result":{First MQL result here},
"code": "/api/status/ok"
},
"q2": {
"result":[{Second MQL result here}],
"code": "/api/status/ok"
},
"status": "200 OK",
"code": "/api/status/ok",
"transaction_id":[opaque string value]
}
As specified on that link. I also came across some of the question on SO, which are -
Freebase python
Multiple Queries in MQL on Freebase
But they seems to be using the old API which is "api.freebase.com". The updated API is "www.googleapis.com/freebase"
I tried the following code, but its not working.
import json
import urllib
api_key = "freebase_api_key"
service_url = 'https://www.googleapis.com/freebase/v1/mqlread'
query1 = [{'id': None, 'name': None, 'type': '/astronomy/planet'}]
query2 = [{'id': None, 'name': None, 'type': '/film/film'}]
envelope = {
'q1':query1,
'q2':query2
}
encoded = json.dumps(envelope)
params = urllib.urlencode({'query':encoded})
url = service_url + '?' + params
print url
response = json.loads(urllib.urlopen(url).read())
print response
I am getting error as
{u'error': {u'code': 400, u'message': u'Type /type/object does not have property q1', u'errors': [{u'domain': u'global', u'message': u'Type /type/object does not have property q1', u'reason': u'invalid'}]}}
How can I embed multiple queries into a single MQL query
I'd suggest looking at the Batch capability of the Python client library for the Google APIs.

AWS CloudSearch cannot upload documents

I am new to AWS and CloudSearch. I have written a very simple app which is to upload docx document (already use cs-import-document to convert to JSON format) to my seach domain.
Code is very straightforward as this:
using (var searchdomainclient = new AmazonCloudSearchDomainClient("http://search-xxxxx-xysjxyuxjxjxyxj.ap-southeast-2.cloudsearch.amazonaws.com"))
{
// Test to upload doc
var uploaddocrequest = new UploadDocumentsRequest()
{
FilePath = #"c:\temp\testsearch.sdf", //docx to JSON already
ContentType = ContentType.ApplicationJson
};
var uploadresult = searchdomainclient.UploadDocuments(uploaddocrequest);
}
However the exception I got is: "Root element is missing."
Here is the JSON stuff in the sdf file I want to upload:
[{
"type": "add",
"id": "c:_temp_testsearch.docx",
"fields": {
"template": "Normal.dotm",
"application_name": "Microsoft Office Word",
"paragraph_count": "1",
"resourcename": "testsearch.docx",
"date": "2014-07-28T23:52:00Z",
"xmptpg_npages": "1",
"page_count": "1",
"publisher": "",
"creator": "John Smith",
"creation_date": "2014-07-28T23:52:00Z",
"content": "Test5",
"author": "John Smith",
"last_modified": "2014-07-29T04:22:00Z",
"revision_number": "3",
"line_count": "1",
"application_version": "15.0000",
"last_author": "John Smith",
"character_count": "5",
"character_count_with_spaces": "5",
"content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}
}]
So what's wrong with my approach?
Thanks heaps!
P.S. I can manually upload docx doc to that search doamin and use C# code to apply search.
============= Update 2014-08-04 ===================
I am not sure whether it is related to this or not. In the stack trace I found it tries to parse as XML file rather than JSON. But from my code I already set ContentType = JASON, but it seems no effect.
at System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo(String res)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at Amazon.Runtime.Internal.Transform.XmlUnmarshallerContext.Read()
at Amazon.Runtime.Internal.Transform.ErrorResponseUnmarshaller.Unmarshall(XmlUnmarshallerContext context)
at Amazon.Runtime.Internal.Transform.JsonErrorResponseUnmarshaller.Unmarshall(JsonUnmarshallerContext context)
at Amazon.CloudSearchDomain.Model.Internal.MarshallTransformations.UploadDocumentsResponseUnmarshaller.UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode)
at Amazon.Runtime.Internal.Transform.JsonResponseUnmarshaller.UnmarshallException(UnmarshallerContext input, Exception innerException, HttpStatusCode statusCode)
at Amazon.Runtime.AmazonWebServiceClient.HandleHttpWebErrorResponse(AsyncResult asyncResult, WebException we)
at Amazon.Runtime.AmazonWebServiceClient.getResponseCallback(IAsyncResult result)
at Amazon.Runtime.AmazonWebServiceClient.endOperation[T](IAsyncResult result)
at Amazon.CloudSearchDomain.AmazonCloudSearchDomainClient.EndUploadDocuments(IAsyncResult asyncResult)
at Amazon.CloudSearchDomain.AmazonCloudSearchDomainClient.UploadDocuments(UploadDocumentsRequest request)
at Amazon.CloudSearchDomain.Model.Internal.MarshallTransformations.UploadDocumentsResponseUnmarshaller.UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode)
Your document id contains invalid characters (period and colon). From https://aws.amazon.com/articles/8871401284621700 :
The ID must be unique across all of the documents you upload to the
domain and can contain the following characters: a-z (lowercase
letters), 0-9, and the underscore character (_). Document IDs must
start with a letter or number and can be up to 64 characters long.
It is also unclear what endpoint you're posting to but you may also have a problem there.
I had exactly the same exception with SDK version 2.2.2.0. When I had updated SDK to version 2.2.2.1 exception went away.

Why does FQL return different user IDs to Graph API

I want to see which users can see a particular album. I use the following query to get my albums and their privacy settings:
SELECT id,allow,deny,description,friends,value FROM privacy WHERE id IN
(SELECT object_id FROM album WHERE owner=me())
and it returns something like this for each album:
{
"id": 212102865605678,
"allow": "211824028961234,212367312342178",
"deny": null,
"description": "John Doe, Work People",
"friends": "SOME_FRIENDS",
"value": "CUSTOM"
}
The second ID in the allow column is right. That's the ID for the 'Work People' friendlist.
But the other ID isn't really the ID of 'John Doe'.
If I use the FB.api from javascript using 'me/friends' I get this:
{
"name": "John Doe",
"id": "100005318169867"
}
Same name, but different ID. I'm quite certain that they're the same user (I don't have many friends). Is this the difference between some internal database ID and external ID?
Any help would be greatly appreciated!