Google App Engine: เป็นไปได้ไหมที่จะทำแบบสอบถาม Gql LIKE


123

ง่ายจริงๆ ใน SQL ถ้าฉันต้องการค้นหาช่องข้อความสำหรับอักขระสองสามตัวฉันสามารถทำได้:

SELECT blah FROM blah WHERE blah LIKE '%text%'

เอกสารสำหรับ App Engine ไม่ได้กล่าวถึงวิธีการบรรลุเป้าหมายนี้ แต่เป็นปัญหาที่พบบ่อยเพียงพอหรือไม่?


3
ปัญหาต่อเนื่องเกิดจากผู้ที่พยายามใช้ GAE Datastore ราวกับว่าเป็นฐานข้อมูล Relational / ~ SQL การที่ Google แนะนำ GQL ทำให้ผู้คนหันมาสนใจระบบ SQL มากขึ้น อย่างไรก็ตามฉันเข้าใจว่า Google พยายามทำให้การเปลี่ยนแปลงสำหรับทุกคนง่ายขึ้นมากแม้ว่าฉันจะไม่แน่ใจว่านี่เป็นแนวทางที่ถูกต้องก็ตาม
fuentesjr

คำตอบ:


81

BigTable ซึ่งเป็นแบ็คเอนด์ฐานข้อมูลสำหรับ App Engine จะปรับขนาดเป็นหลายล้านระเบียน ด้วยเหตุนี้ App Engine จึงไม่อนุญาตให้คุณทำการสืบค้นใด ๆ ที่จะส่งผลให้เกิดการสแกนตารางเนื่องจากประสิทธิภาพจะไม่ดีสำหรับตารางที่มีการเติมข้อมูลอย่างดี

กล่าวอีกนัยหนึ่งแบบสอบถามทุกรายการต้องใช้ดัชนี นี่คือเหตุผลที่คุณสามารถทำ=, >และ<คำสั่ง (ในความเป็นจริงคุณสามารถทำได้เช่นกัน!=แต่ API ทำสิ่งนี้โดยใช้การรวมกันของ>และ<แบบสอบถาม) นี่คือสาเหตุที่สภาพแวดล้อมการพัฒนาตรวจสอบคำค้นหาทั้งหมดที่คุณทำและเพิ่มดัชนีที่ขาดหายไปในindex.yamlไฟล์ของคุณโดยอัตโนมัติ

ไม่มีวิธีจัดทำดัชนีสำหรับLIKEแบบสอบถามจึงไม่สามารถใช้ได้

ดูเซสชัน Google IO นี้เพื่อรับคำอธิบายที่ดีขึ้นและละเอียดขึ้น


77

ฉันกำลังประสบปัญหาเดียวกัน แต่ฉันพบบางอย่างในหน้าแอพ google app:

เคล็ดลับ: ตัวกรองการค้นหาไม่มีวิธีที่ชัดเจนในการจับคู่เพียงบางส่วนของค่าสตริง แต่คุณสามารถปลอมการจับคู่คำนำหน้าโดยใช้ตัวกรองอสมการ:

db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
            "abc",
            u"abc" + u"\ufffd")

สิ่งนี้ตรงกับเอนทิตี MyModel ทุกตัวที่มีสตริงคุณสมบัติ prop ที่ขึ้นต้นด้วยอักขระ abc สตริง Unicode u "\ ufffd" แสดงถึงอักขระ Unicode ที่ใหญ่ที่สุดเท่าที่จะเป็นไปได้ เมื่อค่าคุณสมบัติถูกจัดเรียงในดัชนีค่าที่อยู่ในช่วงนี้คือค่าทั้งหมดที่ขึ้นต้นด้วยคำนำหน้าที่กำหนด

http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html

บางทีนี่อาจทำเคล็ดลับ;)


6
+1 สิ่งนี้ควรค่าแก่การชี้ให้เห็นว่าเป็นกรณี ๆ ไป โชคดีที่ข้อมูลในฟิลด์ที่ฉันกำลังค้นหาถูกแปลงเป็นตัวพิมพ์เล็กก่อนที่จะจัดเก็บ
Cuga

12

Altough App Engine ไม่สนับสนุนคำสั่งเหมือนได้ดูที่คุณสมบัติที่ListPropertyและStringListProperty เมื่อทำการทดสอบความเท่าเทียมกันกับคุณสมบัติเหล่านี้การทดสอบจะถูกนำไปใช้กับสมาชิกรายชื่อทั้งหมดเช่นlist_property = valueทดสอบว่าค่านั้นปรากฏที่ใดในรายการหรือไม่

บางครั้งคุณลักษณะนี้อาจใช้เป็นวิธีแก้ปัญหาเมื่อไม่มีข้อความค้นหา LIKE ตัวอย่างเช่นทำให้สามารถค้นหาข้อความอย่างง่ายตามที่อธิบายไว้ในโพสต์นี้


3
ไม่มีโพสต์นี้แล้ว
mwm

9

คุณจำเป็นต้องใช้บริการค้นหาเพื่อดำเนินการค้นหาข้อความเต็มคล้ายกับ LIKESQL

Gaelykให้ภาษาเฉพาะโดเมนในการดำเนินการมากขึ้นใช้งานง่ายคำค้นหา ตัวอย่างเช่นตัวอย่างต่อไปนี้จะพบหนังสือสิบเล่มแรกที่เรียงลำดับจากเล่มล่าสุดที่มีชื่อเรื่องfern และประเภทที่ตรงกันทั้งหมดthriller:

def documents = search.search {
    select all from books
    sort desc by published, SearchApiLimits.MINIMUM_DATE_VALUE
    where title =~ 'fern'
    and genre =  'thriller'
    limit 10
}

=~เช่นเดียวกับที่เขียนเป็นผู้ประกอบการจับคู่ของ Groovy รองรับฟังก์ชันต่างๆเช่นdistance(geopoint(lat, lon), location)กัน


4

App Engine เปิดตัวบริการค้นหาข้อความเต็มวัตถุประสงค์ทั่วไปในเวอร์ชัน 1.7.0 ที่รองรับพื้นที่เก็บข้อมูล

รายละเอียดในประกาศ .

ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้งาน: https://cloud.google.com/appengine/training/fts_intro/lesson2


3

ดู Objectify ที่นี่ซึ่งเป็นเหมือน API การเข้าถึง Datastore มีคำถามที่พบบ่อยเกี่ยวกับคำถามนี้โดยเฉพาะนี่คือคำตอบ

ฉันจะทำแบบสอบถาม like ได้อย่างไร (เช่น "foo%")
คุณสามารถทำบางอย่างเช่น startWith หรือ endWith ถ้าคุณย้อนกลับลำดับเมื่อจัดเก็บและค้นหา คุณทำการสืบค้นช่วงที่มีค่าเริ่มต้นที่คุณต้องการและค่าที่อยู่เหนือค่าที่คุณต้องการ

String start = "foo";
    ... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");

1
มันจะค้นหา "ขึ้นต้นด้วย" ไม่ใช่ "ประกอบด้วย"
Hardik Patel

1

เพียงทำตามที่นี่: init.py # 354 "> http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/search/ init .py # 354

มันได้ผล!

class Article(search.SearchableModel):
    text = db.TextProperty()
    ...

  article = Article(text=...)
  article.save()

To search the full text index, use the SearchableModel.all() method to get an
instance of SearchableModel.Query, which subclasses db.Query. Use its search()
method to provide a search query, in addition to any other filters or sort
orders, e.g.:

  query = article.all().search('a search query').filter(...).order(...)

1

ฉันทดสอบสิ่งนี้ด้วย Java API ระดับต่ำของ GAE Datastore ฉันและทำงานได้อย่างสมบูรณ์

    Query q = new Query(Directorio.class.getSimpleName());

    Filter filterNombreGreater = new FilterPredicate("nombre", FilterOperator.GREATER_THAN_OR_EQUAL, query);
    Filter filterNombreLess = new FilterPredicate("nombre", FilterOperator.LESS_THAN, query+"\uFFFD");
    Filter filterNombre =  CompositeFilterOperator.and(filterNombreGreater, filterNombreLess);

    q.setFilter(filter);

1
สิ่งนี้ใช้ได้กับคำนำหน้า แต่ถ้าฉันต้องการจับคู่จากท้ายสตริงล่ะ? เช่น - ฉันต้องการค้นหา abc ใน sdfdsabc จากนั้นควรส่งคืน sdfdsabc
user1930106

1

โดยทั่วไปแม้ว่านี่จะเป็นโพสต์เก่า แต่วิธีการสร้าง 'LIKE' หรือ 'ILIKE' คือการรวบรวมผลลัพธ์ทั้งหมดจากแบบสอบถาม '> =' จากนั้นวนซ้ำผลลัพธ์ใน python (หรือ Java) สำหรับองค์ประกอบที่มีสิ่งที่คุณ กำลังมองหา

สมมติว่าคุณต้องการกรองผู้ใช้ที่ได้รับ aq = 'luigi'

users = []
qry = self.user_model.query(ndb.OR(self.user_model.name >= q.lower(),self.user_model.email >= q.lower(),self.user_model.username >= q.lower()))

for _qry in qry:
 if q.lower() in _qry.name.lower() or q.lower() in _qry.email.lower() or q.lower() in _qry.username.lower():
      users.append(_qry)

1

เป็นไปไม่ได้ที่จะทำการค้นหา LIKE บนเครื่องมือแอป datastore การสร้าง Arraylist จะทำอย่างไรหากคุณต้องการค้นหาคำในสตริง

@Index
    public ArrayList<String> searchName;

จากนั้นค้นหาในดัชนีโดยใช้ objectify

List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();

และสิ่งนี้จะให้รายการที่มีรายการทั้งหมดที่มีโลกที่คุณค้นหา


0

หากLIKE '%text%'เปรียบเทียบกับคำหรือสองสามคำเสมอ (คิดว่าการเรียงสับเปลี่ยน) และข้อมูลของคุณเปลี่ยนแปลงอย่างช้าๆ (อย่างช้าๆหมายความว่ามันไม่แพงเกินห้ามใจ - ทั้งราคาที่ชาญฉลาดและประสิทธิภาพที่ชาญฉลาดในการสร้างและอัปเดตดัชนี) จากนั้น Relation Index Entity (RIE) อาจเป็นคำตอบ

ใช่คุณจะต้องสร้างเอนทิตีที่เก็บข้อมูลเพิ่มเติมและเติมข้อมูลให้เหมาะสม ใช่มีข้อ จำกัด บางอย่างที่คุณจะต้องเล่น (ข้อ จำกัด หนึ่งคือ 5000 สำหรับความยาวของคุณสมบัติรายการในที่เก็บข้อมูล GAE) แต่การค้นหาที่ได้นั้นรวดเร็วปานสายฟ้าแลบ

สำหรับรายละเอียดโปรดดูRIEของฉันด้วย Java และ OjbectifyและRIE พร้อมโพสต์Python


0

"ถูกใจ" มักใช้แทนการค้นหาข้อความของคนยากจน สำหรับการค้นหาข้อความก็เป็นไปได้ที่จะใช้หวือ-AppEngine

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.